Source push not allowed in this org. Source tracking is not enabled.
You ran `sf project deploy start` (or `sfdx force:source:push`) against an org that doesn't have source tracking — production, a fully-copied sandbox, or a developer-edition org without the right setting. Source push only works in scratch orgs and (since 2022) sandboxes with source tracking enabled. For non-tracked orgs, use `sf project deploy start` in *target-only* mode or use change sets.
Also seen asSource tracking is not enabled·Source push not allowed·Source tracking not available in this org·sf project deploy start cannot push
A new developer joined the team this morning. They cloned the repo, authenticated to a sandbox, and tried to push their first change with sf project deploy start --target-org devhub-sandbox. The CLI responded with: "Source push not allowed in this org. Source tracking is not enabled." They tried sf project deploy --legacy and got told that the command no longer exists. They opened a Slack thread.
What the CLI is actually telling you
Salesforce's CLI supports two deploy models. The first is metadata-based deploy, which uses the metadata API to ship a manifest of components into any org. The second is source tracking, which keeps the org and a local workspace in sync by recording every change on both sides and computing a delta on demand.
The two models use different commands and different org types. Metadata deploy uses sf project deploy start against the --target-org flag. Source tracking uses the same command, but only when the target org has the source tracking feature enabled. Source tracking is enabled by default on scratch orgs and sandboxes created with the Developer Pro or Partial Copy types when the sandbox is created with the source-tracked option. It's not enabled by default on Production, Developer Edition orgs, most older sandboxes, or any org created before the feature shipped.
When you run a source-tracking command (push, pull, status, or any deploy that expects source tracking) against an org without the feature, the CLI rejects the operation with the message in the error title. You haven't done anything wrong with your code; the target org just doesn't support the model the command requires.
The broken example
A developer cloned a repo with this sfdx-project.json:
{
"packageDirectories": [{ "path": "force-app", "default": true }],
"namespace": "",
"sfdcLoginUrl": "https://login.salesforce.com",
"sourceApiVersion": "60.0"
}
They authenticated to a Developer Edition org:
sf org login web --alias my-dev-org --instance-url https://login.salesforce.com
Then ran:
sf project deploy start --target-org my-dev-org --source-dir force-app/main/default/classes/CaseTriggerHandler.cls
The deploy ran. The class shipped. The next day they wanted to push a batch of related changes and ran:
sf project deploy push --target-org my-dev-org
The CLI rejected it: "Source push not allowed in this org. Source tracking is not enabled."
The first command worked because deploy start is metadata-mode and supports any org. The second command failed because deploy push is source-tracking-mode and requires the feature on the target org. Same project, different commands, different requirements.
A second shape: a developer with a sandbox they refresh weekly. They created the sandbox before source tracking was widely available, so the feature was never enabled. Every weekly refresh keeps the same configuration. Six months later, the CLI still rejects push commands even though the documentation suggests they should work.
A third shape: a CI pipeline that calls sf project deploy push and works against scratch orgs created on demand. The pipeline is pointed at a Developer Edition org for hotfix deploys. Same code, same pipeline, different org, and the push silently fails.
The fix, ordered by what's most likely to apply
For a scratch org, enable source tracking in the scratch org definition file. Scratch orgs honor the sourceTracking flag in config/project-scratch-def.json. The default is true for orgs created via sf org create scratch, but check that the flag isn't being overridden by a definition file your team customized:
{
"orgName": "Acme Dev",
"edition": "Developer",
"features": ["EnableSetPasswordInApi"],
"sourceTracking": true
}
Recreate the scratch org with the corrected definition. The new org will accept source tracking commands.
For a sandbox, create a new sandbox of a type that supports source tracking. Setup, Sandboxes, New Sandbox, and choose the Developer or Developer Pro type. On the create form, check the "Enable source tracking" option. The sandbox provisions with source tracking enabled and supports push/pull commands.
Existing sandboxes cannot have source tracking turned on after the fact. The feature is set at sandbox creation. To migrate, create a new sandbox with the flag set and point your local workspace at it.
For Production, Developer Edition orgs, or older sandboxes, use metadata-mode commands instead of source-tracking commands. The two command families are:
# Source tracking mode
sf project deploy push --target-org my-org
sf project retrieve start --target-org my-org
# Metadata mode (works on any org)
sf project deploy start --source-dir force-app --target-org my-org
sf project retrieve start --source-dir force-app --target-org my-org
For metadata-mode workflows, you specify the components to ship via --source-dir, --metadata, or --manifest. There's no "pending changes" concept; you choose what to deploy each time.
The fixed example
A workflow file that supports both org types by checking the target org's capabilities first:
#!/usr/bin/env bash
set -euo pipefail
ORG_ALIAS="${1:?Pass the org alias as the first argument}"
# Check whether the org supports source tracking
TRACK_ENABLED=$(sf org display --target-org "$ORG_ALIAS" --json | jq -r '.result.tracksSource')
if [[ "$TRACK_ENABLED" == "true" ]]; then
echo "Source tracking enabled. Using push."
sf project deploy push --target-org "$ORG_ALIAS"
else
echo "Source tracking disabled. Using metadata deploy."
sf project deploy start --source-dir force-app --target-org "$ORG_ALIAS"
fi
The script branches on the org's tracksSource capability. Scratch orgs and properly-configured sandboxes use push. Production and legacy orgs use metadata deploy. A single command works against any target.
Why the two models exist
Source tracking is the newer model and the one Salesforce recommends for active development. The platform keeps a server-side record of every metadata change. The CLI compares the server record with the local workspace and computes a precise delta. You don't have to remember which files you changed; the tooling knows.
Metadata deploy is the older model and the only model available before source tracking shipped. The developer is responsible for specifying which components to deploy. The CLI sends exactly what you ask for, no more, no less.
Production should remain on metadata deploy because the production org's history shouldn't be tied to any one developer's workspace. Multiple sandboxes, multiple developers, and multiple deploys converge into production via CI/CD pipelines that ship explicit manifests. A source-tracking model would be ambiguous about whose "pending changes" are authoritative.
Active development should use source tracking because the iteration speed is much higher. The developer changes a class in VS Code, runs push, and the org reflects the change. No manifest, no thinking about which files to include.
When the message confuses scratch org features
A subtle variant of the error: a scratch org created from a definition that doesn't enable source tracking. The sourceTracking flag defaults to true, but a team might explicitly set it to false to simulate a Production deploy environment for testing CI pipelines. If a developer mistakenly uses that scratch org for active work, they get the same "source tracking not enabled" message.
The fix is the same: either create a new scratch org with sourceTracking: true for active dev, or switch to metadata-mode commands when you need to test the no-tracking environment.
CLI command equivalents
A reference table for moving between the two modes:
| Source tracking command | Metadata equivalent |
|---|---|
sf project deploy push | sf project deploy start --source-dir force-app |
sf project retrieve start (with tracking) | sf project retrieve start --metadata ApexClass |
sf project deploy preview | Run sf project deploy validate on a manifest |
sf project delete tracking | Not applicable; metadata mode has no tracking state |
For most workflows, replacing push with deploy start --source-dir force-app works. The full project deploys instead of the delta. On a clean workspace, the two are equivalent.
Diagnosing in CI
A CI pipeline that fails with this error usually does so because the target org isn't what the CI author expected. Common causes:
The org alias resolved to a Production org instead of a sandbox. Check the auth setup; aliased orgs in CI can shift if the auth url isn't pinned.
The sandbox was refreshed and the new sandbox is a different type than the old one. Source tracking is per-sandbox; refresh creates a new instance that might lack the feature.
The CI script was authored against scratch orgs and copy-pasted into a job that targets a sandbox. The command set is the same in spelling, different in semantics.
The mitigation: check the org's tracksSource capability at the start of the script and branch on it. Or standardize on metadata-mode commands across all CI jobs and accept the small extra effort of specifying what to deploy.
Closely related CLI errors
| Error | Cause |
|---|---|
| "Source push not allowed in this org. Source tracking is not enabled." | Source tracking command run against a non-tracking org |
| "There are no source-tracked artifacts in the org" | Tracking command on a tracking org with no pending changes |
| "No AuthInfo found for name <alias>" | Org alias not registered or has been logged out |
| "The deploy/retrieve failed: REQUEST_RUNNING_TOO_LONG" | Deploy timeout, often from a large delta |
The first two are about the source-tracking model. The third is about auth. The fourth is about deploy size.
Migrating from sfdx to sf
The newer sf CLI replaces the older sfdx binary. Both binaries exist on most developer machines for transitional reasons, but they have slightly different command shapes and slightly different behavior around source tracking.
The older command was sfdx force:source:push. The new equivalent is sf project deploy push. The error message is similar across both, but the underlying capability check is the same: source tracking has to be enabled on the target org.
A common confusion: a developer reads a stack-overflow answer from 2022, runs an sfdx command, gets the same error, and assumes the CLI is broken. The CLI works fine; the org just doesn't support the operation. Migrate the workflow to the sf binary and the error remains the same, but the rest of your tooling is on supported commands.
Defensive habits
Standardize on metadata-mode commands in CI scripts. The commands work against any org and survive sandbox refreshes without re-engineering.
Use source-tracking commands for local dev against scratch orgs and source-tracked sandboxes. The iteration speed is worth it.
Check sf org display --target-org <alias> --json | jq .result.tracksSource when in doubt. The capability is what determines which command set works.
Pin auth in CI to specific orgs by url, not by alias. Aliases can drift; urls cannot.
Further reading from Salesforce
Related dictionary terms
Share this fix
Related Salesforce errors
ENOENT: no such file or directory
CLI · sfThe Salesforce CLI couldn't find a file or directory you referenced. Almost always a working-directory mismatch — the CLI is running in `/so…
ERROR running force:auth:web:login: Invalid login URL
CLI · sfThe Salesforce CLI couldn't authenticate against the URL you gave it. Either the URL is wrong (typo, missing https, hitting a non-Salesforce…
My Domain is required for this org / Lightning components require My Domain to be deployed
CLI · sfMany Salesforce features (Lightning components, Connected Apps, single sign-on, Communities) require My Domain to be set up in the org. New …
The resource ... is not allowed by API version <X>
CLI · sfYour sf CLI (or the metadata API call) is using an API version older or newer than what the requested resource supports. Either upgrade the …
@wire(getRecord, ...) requires the fields property
Lightning · LWCYou used `getRecord` from `lightning/uiRecordApi` without specifying which fields to fetch. LDS doesn't auto-fetch all fields like an old-sc…