{"record":{"id":"e91f12103c486632","repo":"benbjohnson/litestream","slug":"host-required-for-sftp-replica","errorCode":null,"errorMessage":"host required for sftp replica","messagePattern":"host required for sftp replica","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/litestream/main.go","lineNumber":1836,"sourceCode":"\n\t\t// Only apply URL parts to field that have not been overridden.\n\t\tif host == \"\" {\n\t\t\thost = u.Host\n\t\t}\n\t\tif user == \"\" && u.User != nil {\n\t\t\tuser = u.User.Username()\n\t\t}\n\t\tif password == \"\" && u.User != nil {\n\t\t\tpassword, _ = u.User.Password()\n\t\t}\n\t\tif path == \"\" {\n\t\t\tpath = u.Path\n\t\t}\n\t}\n\n\t// Ensure required settings are set.\n\tif host == \"\" {\n\t\treturn nil, fmt.Errorf(\"host required for sftp replica\")\n\t} else if user == \"\" {\n\t\treturn nil, fmt.Errorf(\"user required for sftp replica\")\n\t}\n\n\t// Build replica.\n\tclient := sftp.NewReplicaClient()\n\tclient.Host = host\n\tclient.User = user\n\tclient.Password = password\n\tclient.Path = path\n\tclient.KeyPath = c.KeyPath\n\tclient.HostKey = c.HostKey\n\n\t// Set concurrent writes if specified, otherwise use default (true)\n\tif c.ConcurrentWrites != nil {\n\t\tclient.ConcurrentWrites = *c.ConcurrentWrites\n\t}\n","sourceCodeStart":1818,"sourceCodeEnd":1854,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/cmd/litestream/main.go#L1818-L1854","documentation":"After applying URL-derived values, newSFTPReplicaClientFromConfig requires a non-empty host. The SFTP replica client cannot connect without an SSH host, so if neither 'host' nor the host component of 'url' was provided, this error is returned at startup.","triggerScenarios":"An sftp replica with no 'host' field and a 'url' whose host part is empty (e.g. url: 'sftp:///backup' or a bare path), or no url at all.","commonSituations":"Config with only user/path/key-path fields assuming host comes from an environment variable that was unset; malformed url like 'sftp:/backup' (single slash) that parses with an empty host.","solutions":["Add 'host: <sftp-server>' to the sftp replica config","Or set a full URL including host: 'url: sftp://user@hostname/path'","Check that any env var used to build the config is actually set at process start"],"exampleFix":"# before\n- type: sftp\n  user: backup\n  path: /srv/backup\n# after\n- type: sftp\n  host: backup.example.com\n  user: backup\n  path: /srv/backup","handlingStrategy":"validation","validationCode":"if rep.Type == \"sftp\" {\n    host := rep.Host\n    if host == \"\" && rep.URL != \"\" {\n        if u, err := url.Parse(rep.URL); err == nil { host = u.Host }\n    }\n    if host == \"\" { return fmt.Errorf(\"sftp replica %s: missing host\", rep.Name) }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set host explicitly for sftp replicas","Use full URLs (scheme://user@host/path) to avoid empty-host parses","Check env-var expansion at deploy time so hosts aren't blank"],"tags":["config","sftp","litestream","ssh"],"backgroundTag":"missing-required-config-field","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}