39 minutes ago
We need a reliable way to stop a service in an isolated test project using an environment-scoped project token. We are checking this before starting further test deployments; this is not a live production outage.
At 2026-11-11 12:32:31 UTC, Railway CLI 5.71.0 returned exit code 1 for this command (IDs redacted):
railway scale -p <PROJECT_ID> -e <ENVIRONMENT_ID> -s <SERVICE_ID> sfo=0 --jsonExact output:
Unauthorized. Please check that your RAILWAY_TOKEN is valid and has access to the resource you're trying to use.The token was supplied through RAILWAY_TOKEN. With the same token, query { projectToken { projectId environmentId } } returned the expected project and environment IDs. The scale command was attempted once; subsequent checks showed no scale, environment-patch, or deployment changes. The temporary token was then revoked.
The target environment is named production in Railway, but belongs to our isolated test project. The service has one replica configured in sfo and had zero running replicas at the time of the check.
We reviewed https://docs.railway.com/cli/scale and the v5.71.0 scale implementation. We also found https://github.com/railwayapp/cli/issues/1333 and https://github.com/railwayapp/cli/issues/1334, but those concern IaC/config plan, so we cannot assume the same cause here.
Could you clarify:
- Is railway scale, including setting a region to zero, supported with an environment-scoped project token?
- What safe read-only diagnostic can identify which prerequisite query or permission is being rejected? We do not have a trace ID or GraphQL error path for the CLI failure.
- If this CLI path is not supported, what is the documented least-privilege way to stop the test service without using a broader account/workspace token?
No token values or application secrets are included.
3 Replies
38 minutes ago
Project tokens are scoped to a single environment and are meant for deployment-related actions. The examples we document for them are railway up, railway redeploy, and railway logs, and railway scale is not one of them. Scaling commits an environment configuration change rather than acting on a deployment. So a successful projectToken { projectId environmentId } query does not show that scale is permitted, and we have not confirmed which request inside the CLI was refused.
For a read-only check, run railway api with the token and the query you want to probe. It prints the GraphQL errors array, and --allow-errors keeps the exit status at zero so you can inspect it.
To stop the service without rebuilding, use the public deploymentStop mutation on the active SUCCESS deployment. Stop is asynchronous, so poll deployment(id:) until deploymentStopped is true, replicaStatus.running is 0, and each instance reports STOPPED. deploymentRestart on the same deployment ID resumes those containers, but only while they still exist. Setting a region to 0 is not a no-build pause, because that change goes through a new deployment. We have not verified that an environment-scoped project token is accepted by deploymentStop, so test it with the probe above first. At the time of your check the service already had zero running replicas, so there was nothing to stop.
Status changed to Awaiting User Response Railway • 38 minutes ago
35 minutes ago
We have now narrowed the failure to the read-only Regions query used by CLI v5.71.0, before any scaling mutation. On 2026-11-11 (UTC), using one temporary environment-scoped project token:
- 12:54:47: projectToken returned the expected project/environment identity.
- 12:54:48: the CLI Project query returned HTTP 200 with no GraphQL errors.
- 12:54:49: the CLI EnvironmentInstances query returned HTTP 200 with no GraphQL errors.
- 12:54:50: the CLI Regions query, with the correct projectId, returned HTTP 200 and this GraphQL error:
{"message":"Not Authorized","locations":[{"line":1,"column":37}],"path":["regions"],"extensions":{"code":"INTERNAL_SERVER_ERROR"},"traceId":"4976688646426421577"}Exact query source: https://github.com/railwayapp/cli/blob/v5.71.0/src/gql/queries/strings/Regions.graphql
query Regions($projectId: String) { regions(projectId: $projectId) { name region country location workspaceId deploymentConstraints { deprecationInfo { isDeprecated replacementRegion } } } }We stopped at this first rejection. No mutations or further retries were made. The token was revoked and revocation verified; the runner remains at zero running replicas. This isolates the root regions operation, not a specific requested subfield. It is a GraphQL access rejection, not an HTTP 403/Cloudflare error.
Could Railway confirm whether this Regions query should be available to an environment-scoped project token, and whether its use here explains the scale failure? We also still need confirmation of a supported least-privilege stop/resume path before starting the next test run. We have not executed deploymentStop or deploymentRestart, and the automated reply explicitly leaves project-token permission for deploymentStop unverified.
Status changed to Awaiting Railway Response Railway • 35 minutes ago
33 minutes ago
Your trace matches what we expect: the Not Authorized on regions is an authorization refusal for that token, not a server fault. The INTERNAL_SERVER_ERROR code is just GraphQL's default label on an error that carries no code of its own, which is why it comes back with HTTP 200. Because railway scale runs that query before committing any change, an environment-scoped project token stops there, and that explains the CLI failure. Project tokens are scoped to deployment actions such as railway up, railway redeploy and railway logs, and railway scale is not a supported project-token command.
For stop and resume, the supported path is still deploymentStop and then deploymentRestart on the same SUCCESS deployment ID. Neither one builds anything. Stop is asynchronous, so the call returning does not mean the service has stopped. Treat it as done only once deployment(id:) shows deploymentStopped true, replicaStatus.running at 0, and every instance STOPPED. Restart only works while those stopped containers still exist.
We have not confirmed that a project token is accepted for those two mutations. Running the same railway api probe with a fresh test token against deploymentStop will show whether it is accepted or returns the same Not Authorized. If it is refused, the next narrowest option is a workspace-scoped token, which is limited to that one workspace rather than your whole account.
Status changed to Awaiting User Response Railway • 33 minutes ago