Symptoms
You've spent time building out a configuration change on your Juniper device — a new BGP neighbor, a policy tweak, a firewall filter, maybe an OSPF area adjustment — and when you finally type
commitat the [edit] prompt, something goes wrong. Instead of the clean confirmation you were expecting, you get an error message and the commit fails.
The symptoms vary depending on the root cause, but here's what you might see:
- The CLI returns an error like
commit failed
orerror: configuration check-out failed
- A message indicating the configuration has syntax errors that need to be addressed
- A warning about an exclusive configuration lock held by another session
- Error output pointing to a missing dependency — a referenced policy, prefix-list, or interface that doesn't exist
- A resource limit or memory exhaustion error during commit processing
- The commit appears to start but rolls back automatically
- A generic
error code 2
with no further context
Whatever you're seeing, the good news is that Junos almost always tells you something useful. The trick is knowing how to interpret it. Let's walk through the most common causes, how to identify each one, and how to get back on track.
Root Cause 1: Syntax Error in the Configuration
This is the most common reason a commit fails, and the easiest to fix once you know where to look. Junos validates the entire candidate configuration against its schema before committing anything. If even a single stanza has a structural or type error, the whole commit is rejected — there's no partial commit behavior here.
Syntax errors come up most often when you're editing in text mode with
load mergeor
load replacefrom a file, or when pasting a large config block interactively. A misplaced semicolon, a missing closing bracket, an unrecognized keyword, or a value that doesn't match the expected type will all trigger this. In my experience, pasting from a text editor that quietly converts straight quotes to smart quotes is a surprisingly frequent culprit.
When this happens, the error output is usually direct. You'll see something like:
[edit protocols ospf area 0.0.0.0]
'hello-interval 0';
Value 0 is not within range (1..255)
error: configuration check-out failedOr for a structural issue:
[edit policy-options policy-statement EXPORT-BGP]
'term MATCH-LOCAL then';
syntax error, unexpected ';'
error: configuration check-out failedTo identify syntax errors before committing, always run
commit checkfirst. This validates the configuration without applying it:
infrarunbook-admin@sw-infrarunbook-01# commit check
[edit interfaces ge-0/0/2]
'unit 0';
Missing mandatory statement: 'family'
error: configuration check-out failedThe bracket notation tells you exactly where to look. Navigate straight to that stanza:
infrarunbook-admin@sw-infrarunbook-01# edit interfaces ge-0/0/2 unit 0
infrarunbook-admin@sw-infrarunbook-01# show
description "uplink to core";The
family inetblock is missing entirely. The fix:
infrarunbook-admin@sw-infrarunbook-01# set family inet address 10.10.10.2/30
infrarunbook-admin@sw-infrarunbook-01# top
infrarunbook-admin@sw-infrarunbook-01# commit check
configuration check succeeds
infrarunbook-admin@sw-infrarunbook-01# commit
commit completeIf you loaded a config file and got errors, run
show | compareto review exactly what changed before retrying. I've also found it helpful to pipe through
| no-moreso the full error output doesn't get truncated on long configs:
commit check 2>&1 | no-more.
Root Cause 2: Dependency Missing
Junos enforces referential integrity at commit time. If your configuration references something that doesn't exist — a routing policy, a firewall filter, a prefix-list, a BGP community, a scheduler, an authentication key chain — the commit will fail with a reference error.
This comes up constantly when staging changes in pieces. You apply an export policy to a BGP group before the policy itself has been created. You reference a prefix-list in a route filter but made a typo in the name. You paste in a partial config that assumes a bunch of supporting objects are already in place.
The error message looks like this:
[edit protocols bgp group UPSTREAM-PEERS]
'export EXPORT-TO-UPSTREAM';
Referenced policy 'EXPORT-TO-UPSTREAM' is not defined
error: configuration check-out failedOr for a firewall filter reference:
[edit interfaces ge-0/0/1 unit 0 family inet]
'filter input EDGE-INBOUND';
Referenced filter 'EDGE-INBOUND' is not defined
error: configuration check-out failedTo hunt down what's missing, run
commit checkand then cross-reference. If you're getting a policy reference error, check what policies actually exist:
infrarunbook-admin@sw-infrarunbook-01# show policy-options | match "policy-statement"
policy-statement EXPORT-TO-CORE;
policy-statement IMPORT-FROM-UPSTREAM;If the policy you're referencing doesn't appear in that list, you either need to create it or correct the reference. About half of these errors in practice are typos —
EXPORT-TO-UPSTEAMinstead of
EXPORT-TO-UPSTREAM, or a casing mismatch. The fix is either to define the missing object or correct the reference pointing to it:
infrarunbook-admin@sw-infrarunbook-01# set policy-options policy-statement EXPORT-TO-UPSTREAM term DEFAULT then reject
infrarunbook-admin@sw-infrarunbook-01# commit check
configuration check succeedsDon't just delete the reference to make the commit succeed unless you're certain you don't need it. You might be removing a safety filter or a routing policy that was supposed to be in place.
Root Cause 3: Resource Limit Exceeded
Junos enforces platform resource limits at commit time — maximum number of firewall terms, route filter entries, community members, prefix-list entries, and so on. On lower-end platforms like the EX2300, SRX300 series, or older MX routing engines with constrained memory, these limits are lower than you might assume.
The error in a hard-limit case is usually clear:
[edit firewall family inet filter EDGE-INBOUND]
'term';
Too many firewall terms (maximum is 64000, current configuration has 64001)
error: commit failedBut sometimes the failure is less specific — the routing or management daemon runs out of memory during commit processing and you get a generic error:
mgd: error: commit failed with error code 2
commit failedThat
error code 2form is genuinely unhelpful on its own. Your first move should be to check the system logs for context:
infrarunbook-admin@sw-infrarunbook-01> show log messages | match "commit|rpd|mgd" | last 50
Apr 12 14:32:11 sw-infrarunbook-01 mgd[1423]: UI_COMMIT_COMPLETED: UI commit completed
Apr 12 14:38:55 sw-infrarunbook-01 rpd[1204]: RPD_RT_TABLE_FULL: Routing table inet.0 is full, routes 524288/524288
Apr 12 14:38:55 sw-infrarunbook-01 mgd[1423]: UI_COMMIT_NOT_CONFIRMED: commit failedIn this case the routing table is full — a hard platform limit. You can also check current memory and resource utilization:
infrarunbook-admin@sw-infrarunbook-01> show chassis routing-engine
infrarunbook-admin@sw-infrarunbook-01> show system processes extensive | match "rpd|mgd"Fixing resource limit problems depends on what was actually exhausted. For routing table overflow, you need to filter incoming routes more aggressively upstream or upgrade to a platform with a larger FIB. For firewall term limits, consolidate terms where possible. If storage is the constraint, clean up old commit files:
infrarunbook-admin@sw-infrarunbook-01> file list /config/
infrarunbook-admin@sw-infrarunbook-01> request system storage cleanupYou can also limit how many rollback configurations are retained on flash to reduce storage pressure:
infrarunbook-admin@sw-infrarunbook-01# set system max-configurations-on-flash 5Root Cause 4: Exclusive Lock Held by Another User
When someone opens a configuration session with
configure exclusive, they take a full lock on the candidate configuration. Nobody else can commit — and in some cases nobody can even enter configuration mode — until that session releases the lock. This is intentional behavior, but it's a surprisingly common source of confusion in environments where multiple people share device access.
The error you'll see when trying to commit while an exclusive lock is held by another session:
infrarunbook-admin@sw-infrarunbook-01# commit
error: configuration database locked by:
infrarunbook-admin terminal pts/1 (pid 14322) on since 2026-04-12 13:45:10 UTC
exclusive [edit]
commit failedSometimes the lock is from a stale session — someone was working on the device, their SSH connection dropped, and their session is sitting there holding the lock. The management daemon doesn't always clean these up immediately.
To see who currently has sessions open:
infrarunbook-admin@sw-infrarunbook-01> show system users
1:45PM up 14 days, 2:31, 3 users, load averages: 0.04, 0.03, 0.00
USER TTY FROM LOGIN@ IDLE WHAT
infrarunbook-admin d0 10.10.10.50 1:45PM - cli
infrarunbook-admin p1 10.10.10.50 1:42PM 3 cli
infrarunbook-admin p2 10.10.10.51 1:21PM 23 cli -c 'configure exclusive'If the lock is from a live active session, coordinate with whoever owns it — have them commit or rollback and exit. If it's a stale session from a dropped connection, you can kill it from operational mode:
infrarunbook-admin@sw-infrarunbook-01> request system logout pid 14322I've seen this happen a lot with automation scripts — Ansible playbooks, Python netconf scripts — that grab an exclusive lock and then die mid-run without releasing it. The PID is gone but mgd hasn't noticed yet. In those cases, restarting the management process clears the lock:
infrarunbook-admin@sw-infrarunbook-01> restart management-processBe careful with that command. It'll drop all active CLI sessions briefly. Confirm nobody else is actively working on the device before you proceed. As a general habit, automation scripts should always use a try/finally block pattern to release configuration locks even if the script fails partway through.
Root Cause 5: Candidate Configuration Corrupted
This one is rarer but genuinely painful when it happens. The candidate configuration — the file holding your uncommitted changes — can become corrupted. This can happen due to a system crash mid-edit, a storage error, a botched
loadoperation, or occasionally a Junos bug on older code trains.
When the candidate config is corrupted, you'll often get generic errors that don't point to any specific stanza:
infrarunbook-admin@sw-infrarunbook-01# commit
mgd: error: configuration database is corrupted
commit failedYou might also see configuration mode hang unexpectedly, or
show | compareproducing nonsensical output — additions and deletions that don't correspond to anything you actually changed.
The first thing to try is a rollback to the last known-good state:
infrarunbook-admin@sw-infrarunbook-01# rollback 0
load complete
infrarunbook-admin@sw-infrarunbook-01# commit check
configuration check succeedsrollback 0reloads the active committed configuration and discards all pending changes. Your uncommitted work is gone, but the device is stable. If rollback 0 doesn't resolve it, try rolling back to an older checkpoint:
infrarunbook-admin@sw-infrarunbook-01# rollback ?
Possible completions:
0 2026-04-12 14:30:11 UTC by infrarunbook-admin via cli
1 2026-04-12 09:15:44 UTC by infrarunbook-admin via cli
2 2026-04-11 22:03:17 UTC by infrarunbook-admin via cli
infrarunbook-admin@sw-infrarunbook-01# rollback 1
load complete
infrarunbook-admin@sw-infrarunbook-01# commit check
configuration check succeedsIf the corruption is deeper and the Junos rollback commands themselves are failing, you can examine and restore the raw config files from shell. Only go here as a last resort:
infrarunbook-admin@sw-infrarunbook-01> start shell
% ls -la /config/
total 4312
-rw-r--r-- 1 root wheel 112384 Apr 12 14:30 juniper.conf
-rw-r--r-- 1 root wheel 112301 Apr 12 09:15 juniper.conf.1.gz
-rw-r--r-- 1 root wheel 111988 Apr 11 22:03 juniper.conf.2.gz
% cp /config/juniper.conf /var/tmp/juniper.conf.broken
% gunzip -c /config/juniper.conf.1.gz > /config/juniper.conf
% exitAfter restoring the file manually, reboot the device to ensure mgd re-reads the configuration cleanly. If you're running dual routing engines or a Virtual Chassis, check whether a config synchronization from the backup RE is viable before resorting to shell-level file manipulation.
Root Cause 6: Commit Script Failure
If the device has commit scripts configured — SLAX, XSLT, or Python scripts that run at commit time to validate or transform the configuration — a failure in one of those scripts will abort the commit. This is common in larger deployments that enforce configuration standards through automation.
The error output points you to the script:
infrarunbook-admin@sw-infrarunbook-01# commit
COMMIT-SCRIPT: Error in script 'check-interface-descriptions.slax':
interfaces ge-0/0/4: description is required but not set
error: commit failedCheck what commit scripts are active on the device:
infrarunbook-admin@sw-infrarunbook-01# show system scripts commit
commit {
script check-interface-descriptions.slax;
script enforce-bgp-policy.slax;
}In an emergency you can temporarily mark a script inactive to unblock the commit, then re-enable it afterward:
infrarunbook-admin@sw-infrarunbook-01# set system scripts commit script check-interface-descriptions.slax inactive
infrarunbook-admin@sw-infrarunbook-01# commit
commit complete
infrarunbook-admin@sw-infrarunbook-01# delete system scripts commit script check-interface-descriptions.slax inactive
infrarunbook-admin@sw-infrarunbook-01# commitDon't just disable the script without understanding why it fired. The script is usually enforcing a real standard. Fix the underlying issue — in the example above, add the missing interface description — and commit properly rather than masking the enforcement.
Root Cause 7: Stale or Conflicting Uncommitted Changes
Sometimes the candidate configuration accumulates partial or conflicting changes from previous failed commit attempts or from multiple operators editing the device sequentially without fully cleaning up after themselves. The configuration might look internally consistent when you view specific stanzas but have hidden inconsistencies elsewhere that only surface during full validation.
A useful diagnostic in any confusing commit failure is to run:
infrarunbook-admin@sw-infrarunbook-01# show | compare rollback 1This shows you the full diff between the current candidate configuration and the last committed state. If you see changes you didn't make — deletions or additions in stanzas you haven't touched — something has been accumulating in the candidate config that shouldn't be there.
The cleanest fix is to start fresh:
infrarunbook-admin@sw-infrarunbook-01# rollback 0
load completeThen re-apply only the changes you intended. It's a bit of extra work but far better than committing a configuration containing unknown modifications from a previous incomplete session.
Prevention
Most commit failures are preventable with a few disciplined habits. Run
commit checkbefore every commit — make it muscle memory. It's fast, it catches syntax errors and missing dependencies before they cost you anything, and it costs nothing when it passes. There's genuinely no reason not to.
Use
commit confirmedfor any change that might affect your management path. If the commit causes a connectivity issue and you can't reach the device to fix it, the configuration will automatically roll back after the specified timeout:
infrarunbook-admin@sw-infrarunbook-01# commit confirmed 5
commit confirmed, rollback in 5 minutes
infrarunbook-admin@sw-infrarunbook-01# commit
commit completeThe second
commitconfirms the change and cancels the rollback timer. If you don't issue that second commit within the timeout window — because you lost connectivity — the device rolls back on its own. This is one of Junos's best features and it's underused.
Avoid holding
configure exclusivesessions open longer than necessary. In shared environments, keeping an exclusive lock while you're away from the keyboard blocks everyone else. Use standard
configuremode unless you genuinely need to prevent concurrent edits, and always commit or rollback and exit when you're done with your session.
If you're managing Juniper devices with automation — Ansible, Nornir, PyEZ, or any netconf-based tooling — handle lock acquisition and release explicitly in your code. A try/finally block ensures the lock gets released even if the script fails mid-execution. Stale automation locks are a frustratingly common source of commit failures in shared network environments, and they're entirely avoidable.
Keep Junos reasonably current on your devices. Some commit failures — particularly the cryptic generic ones with error codes rather than readable messages — are bugs in older Junos releases that have since been fixed. Before spending hours debugging a strange commit error, check the Juniper PSIRT advisories and known issues list for your code version. You might find the fix is a software upgrade rather than a configuration change.
Finally, document your commit script enforcement standards somewhere accessible to the whole team. Half of commit script failures I've encountered were from engineers who didn't know the scripts existed, let alone what they enforced. If your organization uses commit scripts for policy enforcement, make sure everyone knows what they check for — it'll save real time during troubleshooting.
