golang/go · error

broken character escaping in pkgconf output

Error message

broken character escaping in pkgconf output

What it means

Thrown by parsePkgConfigOutput in cmd/go/internal/work at end-of-input when the last character was a backslash escape ('\\') with nothing following it. Shell-style escaping in pkg-config output requires a character after the backslash; a dangling backslash is malformed and the parser refuses to guess whether it was meant as an escape or a literal.

Source

Thrown at src/cmd/go/internal/work/exec.go:2044

		case ' ', '\t', '\n':
			if len(flag) > 0 || didQuote {
				flags = append(flags, string(flag))
			}
			flag, didQuote = flag[:0], false
			continue
		}

		flag = append(flag, c)
	}

	// Prefer to report a missing quote instead of a missing escape. If the string
	// is something like `"foo\`, it's ambiguous as to whether the trailing
	// backslash is really an escape at all.
	if quote != 0 {
		return nil, errors.New("unterminated quoted string in pkgconf output")
	}
	if escaped {
		return nil, errors.New("broken character escaping in pkgconf output")
	}

	if len(flag) > 0 || didQuote {
		flags = append(flags, string(flag))
	}
	return flags, nil
}

// Calls pkg-config if needed and returns the cflags/ldflags needed to build a's package.
func (b *Builder) getPkgConfigFlags(a *Action, p *load.Package) (cflags, ldflags []string, err error) {
	sh := b.Shell(a)
	if pcargs := p.CgoPkgConfig; len(pcargs) > 0 {
		// pkg-config permits arguments to appear anywhere in
		// the command line. Move them all to the front, before --.
		var pcflags []string
		var pkgs []string
		for _, pcarg := range pcargs {
			if pcarg == "--" {

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Inspect the .pc file and fix or remove the trailing backslash.
  2. Run `pkg-config --cflags --libs <pkg>` to reproduce and locate the offending flag.
  3. Quote backslashes correctly inside .pc values (use \\\\ for a literal backslash) or switch to forward slashes for paths.
  4. If the .pc file is generated by a build system, fix the generator rather than patching the output by hand.

Example fix

# before — foo.pc
Cflags: -DPATH="C:\tmp\"

# after
Cflags: -DPATH="C:\\tmp\\\\"
Defensive patterns

Strategy: try-catch

Validate before calling

// Reject trailing backslashes in .pc field values before relying on pkg-config:
func noTrailingEscape(s string) error {
    for i := 0; i < len(s); i++ {
        if s[i] == '\\' && (i == len(s)-1 || s[i+1] == '\n') {
            return fmt.Errorf("trailing backslash in pkg-config input")
        }
    }
    return nil
}

Try / catch

if err != nil && strings.Contains(err.Error(), "character escaping in pkgconf") {
    // surface the offending .pc file path to the user and abort
}

Prevention

When it happens

Trigger: A .pc file ending a Cflags/Libs line with a trailing backslash inside a quoted region, e.g. `Cflags: -DMSG="hello\`. pkg-config output that truncates mid-token due to a buffer issue. Hand-edited .pc files with an incomplete escape sequence.

Common situations: CGo projects with #cgo pkg-config. Windows path literals pasted into .pc files using backslashes that the parser then treats as escapes. Buggy pkgconf output. Misconfigured cross-compilation sysroots.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/33bcc9b6562a5fbe. Report an issue: GitHub.