{"record":{"id":"09522b72ac64319c","repo":"benbjohnson/litestream","slug":"user-required-for-sftp-replica","errorCode":null,"errorMessage":"user required for sftp replica","messagePattern":"user required for sftp replica","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/litestream/main.go","lineNumber":1838,"sourceCode":"\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\n\treturn client, nil\n}","sourceCodeStart":1820,"sourceCodeEnd":1856,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/cmd/litestream/main.go#L1820-L1856","documentation":"newSFTPReplicaClientFromConfig requires a username: after merging 'url' userinfo with the 'user' field, the user must be non-empty because the SFTP client needs a login account. This error is returned when both sources are empty.","triggerScenarios":"An sftp replica with no 'user' field and a 'url' lacking userinfo (e.g. 'sftp://host/backup'), so user remains empty after URL application.","commonSituations":"Relying on SSH default user or ssh-agent identity without specifying it (litestream requires an explicit user); a URL like 'sftp://host/db' without user@.","solutions":["Add 'user: <username>' to the sftp replica config","Or include the user in the URL: 'url: sftp://myuser@host/path'","Confirm the auth approach: litestream needs an explicit user even when key-path auth is used"],"exampleFix":"# before\n- type: sftp\n  host: backup.example.com\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    user := rep.User\n    if user == \"\" && rep.URL != \"\" {\n        if u, err := url.Parse(rep.URL); err == nil && u.User != nil { user = u.User.Username() }\n    }\n    if user == \"\" { return fmt.Errorf(\"sftp replica %s: missing user\", rep.Name) }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always specify 'user:' for sftp replicas, even with key auth","Include user@ in the URL when using URL-style config","Never assume SSH defaults apply; litestream requires explicit user"],"tags":["config","sftp","litestream","authentication"],"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"}