Fatal: Bad Ownership or Modes for Chroot Directory
This OpenSSH fatal error means sshd rejected the effective ChrootDirectory security boundary for that connection. Prove which chroot a user's Match/Include context selects, expand its tokens, then inspect every pathname component through the chroot boundary. Those components must be root-owned and not writable by group or others; writable application directories belong inside the protected jail.
fatal: bad ownership or modes for chroot directory or ...directory component.Authentication may succeed before the session closes because the chroot check happens at session startup.Your sshd configuration uses ChrootDirectory, often with SFTP and a Match block.First identify the actual ChrootDirectory used for this account, including any %u or %h expansion. Then inspect the resulting path component by component.
namei -l /path/to/chrootIf namei is unavailable, use ls -ld on / and each successive directory in the path.
Verify: Every component of the chroot pathname is a directory owned by UID 0/root and has no group-write or other-write bit.
Why OpenSSH rejects the chroot
The current OpenSSH sshd_config manual states that at session startup, sshd checks all components of the ChrootDirectory pathname. They must be root-owned directories and not writable by group or others. This check applies to the chroot boundary itself; StrictModes does not disable it.
The OpenSSH implementation also descends the path and rejects a component when its owner UID is not 0 or its mode contains group/other write bits. That is why fixing only the final directory can fail when a parent directory is the offending component.
Fix path #1 — identify the effective chroot before changing permissions
Inspect the relevant SSH configuration, including included files:
grep -RniE '^[[:space:]]*(Include|Match|ChrootDirectory|ForceCommand|Subsystem)[[:space:]]' /etc/ssh/sshd_config /etc/ssh/sshd_config.d 2>/dev/nullGrepping the files reveals candidate directives, but Include and Match rules can make the effective result account/context-specific. Where supported, use OpenSSH effective-configuration output with the appropriate connection criteria to confirm the ChrootDirectory that actually applies. Then resolve tokens such as %u or %h for the affected account before checking ownership.
Verify: The path you inspect is the effective, token-expanded chroot selected for the affected connection context—not merely a global/example directive found by grep.
Fix path #2 — repair only the unsafe chroot boundary component
For each component, compare the current owner and mode with the OpenSSH requirement. Correct only the component you have proven is wrong, using ownership and permissions appropriate to your server design. Do not apply a blanket recursive command.
755 is common, but it is not the universal rule. The security requirement is that each chroot path component is root-owned and not writable by group or others. Preserve any stricter permissions that already satisfy the requirement.Verify: Re-run namei -l (or your component-by-component ls -ld checks) and confirm the complete chroot path now satisfies those conditions.
Keep the chroot root protected; put writable data inside it
The SFTP user's need to upload files does not mean the chroot boundary itself should be user-owned. The strict root-owned/non-group-or-other-writable check applies to the pathname components leading through the configured chroot boundary. Directories created below that boundary can be writable according to the application's access policy. A safer layout separates the protected jail root from a writable workspace:
/sftp/alice/ # chroot boundary: root-owned, not group/other writable
/sftp/alice/uploads/ # writable workspace for alice, as your policy requiresThis separation preserves the OpenSSH chroot requirement while giving the user a location for file operations. Choose the writable directory's owner/group/mode according to your application's access policy rather than copying a broad permission recipe.
Verify: Re-run the component inspection through the exact chroot boundary, then log in as the affected account and confirm it can write only where intended below that boundary. Do not recursively impose root ownership on application data merely because the jail root requires it.
Validate sshd before applying configuration changes
If you edited SSH configuration as part of the repair, keep the current administrative session open and validate before reload:
sudo sshd -tIf validation reports an error, do not reload. If it exits cleanly, use the supported reload mechanism for your OS/control panel while keeping the known-good administrative session open. Test the exact affected account in a separate new SFTP connection before closing that session.
Verify: The fatal chroot ownership/mode message disappears for the same account/context, the user lands inside the intended jail, cannot escape above it, and can write only in the intended subdirectory. If the server now reports a different concrete error, stop applying this chroot-ownership fix and follow the new failure class.
What not to do
chmod 777 on the chroot directory.Do not run recursive chown/chmod across the jail before identifying the failing boundary component.Do not make the SFTP user the owner of the configured chroot boundary merely to allow uploads.Do not remove ChrootDirectory just to make the login succeed.Do not assume mode 755 is the only valid numeric mode; test the actual ownership/writeability requirement.Do not reload sshd after a configuration edit until sshd -t succeeds.Do not call a grep result the effective ChrootDirectory when Match/Include criteria can select another value for the failing connection.Do not recursively make all content below the jail root-owned; writable application data below the protected boundary can follow its intended access policy.Do not stop at “login succeeds”; verify confinement and intended write access separately.Do not keep fixing ownership/modes if the fatal message changes to a different concrete SSH/SFTP error.Still failing? Capture this evidence
namei -l or equivalent ownership/mode output for every path componentthe relevant Match, ChrootDirectory, ForceCommand and Subsystem configurationserver OS/distribution and OpenSSH versionthe result of sshd -twhether login succeeds for a comparable non-chrooted or known-good accounteffective sshd configuration for the affected user/host/address context when Match/Include rules applythe token-expanded ChrootDirectory actually selected for that accountwhether the account remains confined above the jail boundary after repairwhether intended writable subdirectories work without making the chroot boundary writablethe first different error if the original fatal chroot message disappearsReferences
Still stuck? Ask the community
Share the redacted fatal log line, chroot path, component ownership/modes and relevant SSH configuration.
Loading community discussion…