What's Actually Happening
You've set up an Include directive in your SSH config to organize hosts into separate files, but SSH isn't loading the configurations from those files. Hosts defined in included files are ignored, or you get errors about unknown hosts even though they're clearly defined.
The Error You'll See
When trying to connect to a host defined in an included file:
ssh: Could not resolve hostname myserver: Name or service not knownOr when checking with verbose mode:
ssh -G myserver | headThe output shows no settings from the included file, or you see no error but the connection uses wrong settings.
Why This Happens
The Include directive has specific requirements that must be met:
- 1.OpenSSH 7.3 or later is required
- 2.Paths are relative to the directory containing the current file
- 3.File permissions must allow reading
- 4.Wildcards must match actual files
- 5.The Include directive must be in the correct location within the config
Step 1: Check OpenSSH Version
First, verify your SSH version supports Include:
ssh -VYou need OpenSSH 7.3 or later:
OpenSSH_8.9p1 Ubuntu-3ubuntu0.1, OpenSSL 3.0.2 15 Mar 2022If you have an older version, you cannot use Include directives.
Step 2: Verify File Existence and Paths
Check that the included files actually exist:
ls -la ~/.ssh/config.d/If using wildcards, verify they match files:
ls -la ~/.ssh/config.d/*.confYour config should look like:
``` # ~/.ssh/config Include config.d/*.conf
Host default-server HostName example.com ```
Step 3: Check Config Syntax
Test your SSH config for syntax errors:
ssh -G nonexistent-host > /dev/nullIf there's a syntax error, you'll see:
/Users/user/.ssh/config line 5: no argument after keyword "Include"Common syntax errors include:
- Missing newline after Include
- Using quotes when not needed
- Incorrect glob patterns
Step 4: Verify Relative Paths
The Include path is relative to the directory containing the current file. For ~/.ssh/config:
``` # Correct - relative path Include config.d/*.conf
# Correct - absolute path Include ~/.ssh/config.d/*.conf
# Wrong - tilde may not expand Include ~/config.d/*.conf ```
Use absolute paths or paths relative to the config file location.
Step 5: Check File Permissions
SSH is strict about permissions:
ls -la ~/.ssh/Your config files should be readable only by you:
drwx------ 2 user user 4096 .ssh
-rw------- 1 user user 1024 config
-rw------- 1 user user 512 config.d/server1.confFix permissions if needed:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/config
chmod 600 ~/.ssh/config.d/*Step 6: Test with Debug Mode
Run SSH with maximum debug to see config loading:
ssh -vvvG myserver 2>&1 | grep -i includeThis shows which files are being processed:
debug1: /home/user/.ssh/config line 1: Including configuration file /home/user/.ssh/config.d/work.conf
debug1: /home/user/.ssh/config.d/work.conf line 5: Applying options for myserverStep 7: Verify Include Order
Remember that SSH config is first-match-wins. If you have:
``` # ~/.ssh/config Include config.d/*.conf
Host myserver HostName wrong.example.com ```
And in config.d/work.conf:
Host myserver
HostName correct.example.comThe included file is processed first, so correct.example.com wins. But if you put the Include after the Host block, the inline Host block wins.
Verify the Fix
Your Include directives work correctly when:
- 1.
ssh -vvvG hostnameshows "Including configuration file" messages - 2.
ssh -G hostnameshows settings from included files - 3.Hosts defined in included files connect properly
- 4.No syntax errors appear in debug output
Create a test file to verify:
```bash echo 'Host include-test HostName test.example.com' > ~/.ssh/config.d/test.conf
ssh -G include-test | grep hostname ```
You should see hostname test.example.com in the output.