kubernetes/kops · error
unexpected line %q (expected 2 tokens)
Error message
unexpected line %q (expected 2 tokens)
What it means
run() parses the SHA256SUMS response line by line, skipping blank lines and known PGP boilerplate. Any non-empty line that does not split into exactly 2 whitespace-separated tokens (hash, filename) is rejected with this error. It guards against HTML error pages, comments, or unexpected formats corrupting the generated manifest.
Source
Thrown at pkg/assets/assetdata/tools/cmd/generatefileassets/main.go:90
line = strings.TrimSpace(line)
if line == "" {
continue
}
if line == "-----BEGIN PGP SIGNED MESSAGE-----" {
// Start of the PGP boilerplate
continue
}
if line == "-----BEGIN PGP SIGNATURE-----" {
// Part of the PGP signature; end of signed content
break
}
if line == "Hash: SHA256" {
// Part of the PGP boilerplate
continue
}
tokens := strings.Fields(line)
if len(tokens) != 2 {
return fmt.Errorf("unexpected line %q (expected 2 tokens)", line)
}
hash := tokens[0]
name := tokens[1]
name = removeBadPrefix(name)
if exclude.Matches(prefix + name) {
continue
}
m.Files = append(m.Files, file{
Name: prefix + name,
SHA256: hash,
})
}
out, err := yaml.Marshal(&m)
if err != nil {
return fmt.Errorf("building yaml: %w", err)
}View on GitHub (pinned to 4c8573c808)
Solutions
- Inspect the URL content with curl; point -sums at the real plain-text SHA256SUMS file
- Preprocess/handle unusual lines: strip comments or extra columns, or extend the parser to skip them
- If PGP boilerplate differs, add the marker line to the skip list alongside 'Hash: SHA256'
- Verify you downloaded the sha256 (not sha512/md5) sums matching the expected 2-column format
Example fix
// before: HTML error page fed to parser unexpected line "<html>..." (expected 2 tokens) // after: correct sums URL main -sums https://dl.k8s.io/.../SHA256SUMS ...
Defensive patterns
Strategy: validation
Validate before calling
func looksLikeSums(b []byte) bool {
for _, line := range strings.Split(string(b), "\n") {
line = strings.TrimSpace(line)
if line == "" || strings.HasPrefix(line, "-----") || strings.HasPrefix(line, "Hash:") || strings.HasPrefix(line, "<") {
continue
}
if len(strings.Fields(line)) != 2 {
return false
}
}
return true
} Type guard
func isUnexpectedLineErr(err error) bool {
return err != nil && strings.Contains(err.Error(), "unexpected line")
} Try / catch
if err := run(ctx); err != nil {
if isUnexpectedLineErr(err) {
// dump the raw response to inspect what was actually fetched
}
return err
} Prevention
- Curl the sums URL first and confirm it is plain 2-column SHA256SUMS text
- Never point -sums at HTML pages or directory listings
- Extend the PGP-boilerplate skip list if the signature format changes
- Prefer sha256 sums files over checksum formats with extra columns
When it happens
Trigger: The URL returned content that isn't a standard SHA256SUMS file: an HTML error/consent page, a GPG file with unhandled boilerplate lines, lines with extra tokens (checksum files with size columns), or wrapped/continuation lines.
Common situations: Pointing -sums at a login page or a directory listing; using a BSD-style checksum file or one with additional metadata columns; PGP headers differing from the three handled cases.
Related errors
- error parsing addons or manifest: %v
- error parsing addons: %v
- failed to parse objects: %w
- failed to parse objects: %w
- Error too many '=' (%d) in %s
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/d7daa6afab05360e.
Report an issue: GitHub.