kovidgoyal/kitty · warning
passwd line has %d colon delimited fields instead of 7
Error message
passwd line has %d colon delimited fields instead of 7
What it means
ParsePasswdLine splits a line of /etc/passwd (or DSCL output) on colons and expects exactly 7 fields: name, passwd, uid, gid, gecos, home, shell. Any other field count produces this error. It is a strict format validation of passwd-style records.
Source
Thrown at tools/utils/passwd.go:29
"strconv"
"strings"
"sync"
"howett.net/plist"
)
var _ = fmt.Print
type PasswdEntry struct {
Username, Pass, Uid, Gid, Gecos, Home, Shell string
}
func ParsePasswdLine(line string) (PasswdEntry, error) {
parts := strings.Split(line, ":")
if len(parts) == 7 {
return PasswdEntry{parts[0], parts[1], parts[2], parts[3], parts[4], parts[5], parts[6]}, nil
}
return PasswdEntry{}, fmt.Errorf("passwd line has %d colon delimited fields instead of 7", len(parts))
}
func ParsePasswdDatabase(raw string) (ans map[string]PasswdEntry) {
scanner := NewLineScanner(raw)
ans = make(map[string]PasswdEntry)
for scanner.Scan() {
line := scanner.Text()
if entry, e := ParsePasswdLine(line); e == nil {
ans[entry.Uid] = entry
}
}
return ans
}
func ParsePasswdFile(path string) (ans map[string]PasswdEntry, err error) {
raw, err := os.ReadFile(path)
if err != nil {
return nil, errView on GitHub (pinned to 6d5d0c4406)
Solutions
- Inspect the reported line and its field count; fix or discard malformed entries upstream.
- If GECOS may contain colons, split with strings.SplitN(line, ":", 7) so extra colons stay in the GECOS field.
- Skip blank/comment lines before calling ParsePasswdLine.
- Validate input with a regexp like ^([^:]*:){6}[^:]*$ before parsing.
Example fix
// before
parts := strings.Split(line, ":")
// after
parts := strings.SplitN(line, ":", 7)
if len(parts) == 7 { ... } Defensive patterns
Strategy: validation
Validate before calling
if !passwdLineRE.MatchString(line) {
return nil, fmt.Errorf("skipping malformed passwd line: %q", line)
}
// var passwdLineRE = regexp.MustCompile(`^[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*$`) Try / catch
entry, err := utils.ParsePasswdLine(line)
if err != nil {
log.Printf("skipping bad passwd line %q: %v", line, err)
continue
} Prevention
- Use SplitN(line, ":", 7) when GECOS may contain colons.
- Skip blank and '#' comment lines before parsing.
- Diff custom passwd files against vipw/pwck output.
When it happens
Trigger: Feeding ParsePasswdLine a malformed line: missing trailing fields, extra colons in GECOS (e.g. a comment containing ':'), empty lines with colons, or Windows-style line endings leaving stray characters.
Common situations: Parsing hand-edited /etc/passwd files, passwd files from exotic NSS backends, or test fixtures that abbreviate lines. Also GECOS fields containing colons, which inflate the field count.
Related errors
- No user record available for user with UID: %#v
- No user matching the UID: %#v found
- Abstract UNIX sockets are only supported on Linux. Cannot us
- Extra characters at end of search
- Too much piped data
AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27).
Data as JSON: /api/errors/608a66116d52b1d7.
Report an issue: GitHub.