Salesforce Dictionary - Free Salesforce GlossarySalesforce Dictionary
All errors
CLI · sf

The resource ... is not allowed by API version <X>

Your sf CLI (or the metadata API call) is using an API version older or newer than what the requested resource supports. Either upgrade the CLI, change the project's `sourceApiVersion`, or use a feature available in the version you're on.

Also seen asresource not allowed by version·API version mismatch·Resource not allowed·INVALID_VERSION

A release engineer kicks off the CI deployment on a Friday afternoon. The script runs sf project deploy start against the staging org. The pipeline returns The resource /services/data/v55.0/tooling/deployments is not allowed by API version 55.0. Other pipelines on other branches deploy fine. The engineer compares the failing job to the working one and the difference is the project's sourceApiVersion. The team needs to understand how API versions flow through the CLI and how to keep them aligned.

What the platform is checking

Every Salesforce API call carries an API version. The version determines which endpoints exist, which fields are returned, which behaviors apply, and which deprecations are in effect. The CLI assembles requests using either an explicit version flag, a project-level sourceApiVersion, an org-level default, or the CLI binary's bundled default.

When the CLI sends a request to an endpoint that does not exist in the requested version, the platform returns The resource ... is not allowed by API version <X>. The endpoint might exist in newer versions (the request was downgraded) or it might exist in older ones (a deprecated endpoint that was removed). The fix is to align the API version with the endpoint's availability.

The error is precise about the endpoint and version. The CLI does not always make it obvious which version flag produced the request, so diagnosis requires understanding the CLI's version resolution order.

The resolution order is. First, an explicit --api-version (or older --apiversion) flag on the command. Second, the sourceApiVersion in sfdx-project.json. Third, the org-api-version value in sf config. Fourth, the CLI binary's compiled-in default.

A pipeline that worked yesterday and fails today usually has a mismatch in one of these layers. Either the CLI was upgraded and changed its default, or the project file was edited, or the org's default was reset, or a flag was added or removed.

The broken example

A sfdx-project.json file with a stale API version:

{
  "packageDirectories": [
    { "path": "force-app", "default": true }
  ],
  "name": "salesforce-app",
  "namespace": "",
  "sfdcLoginUrl": "https://login.salesforce.com",
  "sourceApiVersion": "55.0"
}

The project was last updated when API version 55.0 was current. The deployment script runs sf project deploy start. The CLI assembles the request at version 55.0 because the project file says so. The endpoint /services/data/v55.0/tooling/deployments was deprecated in version 58.0 in favor of a new metadata API path. The platform refuses the call.

A second shape: a CI pipeline pins the CLI to an older version with npm install -g @salesforce/cli@2.x.y. The bundled defaults use a version that no longer supports a feature the pipeline relies on, such as a metadata type added in a newer release.

A third shape: a developer manually sets --api-version 60.0 on the command line. The org runs API version 62.0 generally but the developer's call uses 60.0. A field added in 61.0 is missing from the response. The deploy succeeds but the resulting record has a null where the developer expected a value.

Why API versions matter beyond endpoint availability

Endpoint availability is the most visible symptom but not the only one. Field availability, default field values, query behavior, and metadata serialization formats all depend on the API version.

A SOQL query that uses a relationship field added in version 60.0 returns an error when called against version 58.0. A Lightning component bundle's lwc:if syntax requires version 56.0 or later in the component's metadata declaration; deploying with an older sourceApiVersion produces parse errors.

Picklist values returned via REST in version 50.0 include all values regardless of the user's permissions; in version 52.0 and later, the response filters to values the user can access. Code that depends on the older behavior breaks when the API version is bumped.

Every Salesforce release notes document includes an "API Version Changes" section. Reading it before a deploy that touches CLI versions saves time.

The fix, three paths

Bump the project to a current API version. The most common cure. Salesforce supports an N-3 versioning policy: the current release plus the previous three are supported. As of API version 62.0 (Spring '26), versions 59 through 62 are first-class. Older versions still work but cannot use features introduced in newer ones.

{
  "sourceApiVersion": "62.0"
}

After the change, run sf project deploy validate to confirm the deploy works at the new version. Some endpoint behaviors change between versions, so the validation catches regressions.

Pin the CLI to a recent version in CI. Keep the CLI roughly aligned with the org's API version. The CLI's own defaults track the platform's release cadence, so a recent CLI usually defaults to a current API version.

# .github/workflows/deploy.yml
steps:
  - name: Install Salesforce CLI
    run: npm install -g @salesforce/cli@latest

Avoid pinning to specific minor versions that may be missing features. Track the major version (2.x) and let the CLI auto-update to the latest patch.

Pass an explicit --api-version flag for commands that have version-specific behavior. When a single command needs to override the project default, pass the flag.

sf data query --query "SELECT Id FROM Account" --api-version 62.0

The override is local to the command. The project file remains the source of truth for general deploys.

The fixed example

A CI workflow that explicitly aligns versions:

name: Deploy to Staging
on:
  push:
    branches: [staging]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Salesforce CLI
        run: npm install -g @salesforce/cli@latest

      - name: Confirm CLI Version
        run: sf --version

      - name: Authenticate to Org
        run: |
          echo "$SF_AUTH_URL" | sf org login sfdx-url \
            --sfdx-url-stdin \
            --alias staging \
            --set-default
        env:
          SF_AUTH_URL: ${{ secrets.SF_AUTH_URL_STAGING }}

      - name: Validate Deploy
        run: sf project deploy validate --target-org staging --test-level RunLocalTests

      - name: Deploy
        if: success()
        run: sf project deploy start --target-org staging --test-level RunLocalTests

The workflow installs the latest CLI, logs its version for auditing, and uses the version in sfdx-project.json for all deploys. No commands pin --api-version because the project's sourceApiVersion is current.

A matching sfdx-project.json:

{
  "packageDirectories": [
    { "path": "force-app", "default": true }
  ],
  "name": "salesforce-staging",
  "sfdcLoginUrl": "https://test.salesforce.com",
  "sourceApiVersion": "62.0"
}

Edge case: API versions in metadata files

Individual Apex classes, triggers, and Lightning components carry their own API version in their -meta.xml files.

<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>62.0</apiVersion>
    <status>Active</status>
</ApexClass>

The class's API version determines which platform APIs are available to its code, which annotations are valid, and how the platform interprets certain syntactic constructs. A class with apiVersion=55.0 cannot use a feature introduced in 60.0 even if the project's sourceApiVersion is 62.0.

A common refactor is to bulk-update all meta XML files to a current version:

find force-app -name '*.cls-meta.xml' -exec \
    sed -i.bak 's|<apiVersion>5[0-9].0</apiVersion>|<apiVersion>62.0</apiVersion>|' {} +

Use the sed snippet selectively. Some legacy classes need older versions to maintain specific behavioral guarantees.

Edge case: managed packages and API versions

Managed packages ship at their publisher's chosen API version. When you install a package, the package's classes carry that version, not your org's project default. Upgrading the package may bump the version; subscribers cannot directly override it.

If your code depends on a package class and the package upgrades to use a newer API endpoint that your org's default version does not support, your callouts fail. The fix is usually to bump your own code's API version to match the package, or to add a thin wrapper that calls the package at the package's version.

Edge case: legacy SOAP API endpoints

The Tooling API, Metadata API, Bulk API, and REST API each have their own version-numbered endpoints. The CLI assembles URLs using the requested version. A mismatch between your project's version and the org's installed API versions can occur if the org is on a different release window (sandboxes lag production by one major release until the org upgrade).

Check the org's API version explicitly:

sf org display --target-org staging --json | jq '.result.apiVersion'

If the org reports 60.0 and your project says 62.0, certain endpoints in your project's chosen version may not exist yet in the staging org. Match your sourceApiVersion to the lowest org version you deploy to.

Edge case: sf command vs legacy sfdx

The sf CLI replaced sfdx in 2023. Both binaries can coexist. They use the same configuration files but expose different flag names (--api-version vs --apiversion). Scripts written for the older sfdx may break on a fresh installation that only has sf.

If your CI invokes sfdx commands, install the compatibility shim or rewrite the script to use sf commands. The flag names are the most common source of subtle errors.

Test patterns

A CI step that validates the API version alignment before deploying:

PROJECT_VERSION=$(jq -r '.sourceApiVersion' sfdx-project.json)
ORG_VERSION=$(sf org display --target-org staging --json | jq -r '.result.apiVersion')
if [ "$PROJECT_VERSION" != "$ORG_VERSION" ]; then
    echo "Project version ($PROJECT_VERSION) does not match org version ($ORG_VERSION)"
    exit 1
fi

The check runs before the actual deploy. A mismatch fails the pipeline early with a clear message instead of a cryptic resource-not-allowed error.

For functional tests, run the CLI commands locally against a scratch org with the target API version. The scratch-org definition can specify the version:

{
  "orgName": "Test Org",
  "edition": "Developer",
  "release": "preview"
}

release: preview pulls the next release's version. Combined with the project's sourceApiVersion, you can test forward-looking changes.

Diagnosing in production

When the error fires:

  1. Run sf --version to identify the CLI version.
  2. Inspect sfdx-project.json for sourceApiVersion.
  3. Inspect any explicit --api-version flags on the failing command.
  4. Run sf org display --json to identify the org's version.
  5. Locate the documentation for the failing endpoint to find when it was added or deprecated.
  6. Choose: bump the project, pin the CLI, or pass an explicit flag.

The investigation is methodical. The version resolution order is fixed, so identifying the layer that produced the wrong version is straightforward once you know to look.

Anti-pattern: relying on CLI defaults silently

A pipeline that does not pin the CLI version inherits whatever the runner installs. CI runners update their package indexes regularly, so the CLI version drifts without notice. A pipeline that worked yesterday can fail today because the CLI's default API version changed.

Pin the CLI in CI. Document the version. Bump deliberately.

Defensive habits

Bump the project's API version with each new Salesforce release. The platform releases three times a year; bumping in lockstep avoids the silent-deprecation problem.

Run sf project deploy validate in CI on every PR. The validation catches version-related deploy issues at PR time.

Document the API version in the project README. Engineers joining the team know which version to expect.

Watch the Salesforce release notes for API-deprecation announcements. Endpoints are marked deprecated at least one release before removal, giving you a window to migrate.

Use scratch orgs for testing forward-looking changes. The release: preview setting on a scratch-org definition pulls the next release; deploy your code there to catch deprecations early.

Quick recovery checklist

  1. Identify the API version the CLI used in the failing call.
  2. Identify which layer produced it (flag, project, config, default).
  3. Bump or pin to align with the endpoint's availability.
  4. Validate the deploy in a sandbox.
  5. Update CI to lock the alignment.

The CLI-version mismatch is operational, not architectural. The fix is short. The work that pays off is the process discipline that prevents drift.

Further reading from Salesforce

Related dictionary terms

Share this fix

Share on LinkedInShare on X

Related Salesforce errors