spf13/viper · error
flag for %q is nil
Error message
flag for %q is nil
What it means
Returned by Viper.BindPFlag (viper.go:1107-1110) when the passed *pflag.Flag is nil. The nil almost always comes from pflag.FlagSet.Lookup(name), which returns nil for a flag that is not defined on that set.
Source
Thrown at viper.go:1109
func (v *Viper) BindPFlags(flags *pflag.FlagSet) error {
return v.BindFlagValues(pflagValueSet{flags})
}
// BindPFlag binds a specific key to a pflag (as used by cobra).
// Example (where serverCmd is a Cobra instance):
//
// serverCmd.Flags().Int("port", 1138, "Port to run Application server on")
// Viper.BindPFlag("port", serverCmd.Flags().Lookup("port"))
func BindPFlag(key string, flag *pflag.Flag) error { return v.BindPFlag(key, flag) }
// BindPFlag binds a specific key to a pflag (as used by cobra).
// Example (where serverCmd is a Cobra instance):
//
// serverCmd.Flags().Int("port", 1138, "Port to run Application server on")
// Viper.BindPFlag("port", serverCmd.Flags().Lookup("port"))
func (v *Viper) BindPFlag(key string, flag *pflag.Flag) error {
if flag == nil {
return fmt.Errorf("flag for %q is nil", key)
}
return v.BindFlagValue(key, pflagValue{flag})
}
// BindFlagValues binds a full FlagValue set to the configuration, using each flag's long
// name as the config key.
func BindFlagValues(flags FlagValueSet) error { return v.BindFlagValues(flags) }
// BindFlagValues binds a full FlagValue set to the configuration, using each flag's long
// name as the config key.
func (v *Viper) BindFlagValues(flags FlagValueSet) (err error) {
flags.VisitAll(func(flag FlagValue) {
if err = v.BindFlagValue(flag.Name(), flag); err != nil {
return
}
})
return nil
}View on GitHub (pinned to 528f7416c4)
Solutions
- Nil-check the Lookup result before binding: if f := flags.Lookup("port"); f != nil { v.BindPFlag("port", f) }.
- Register the flag first (e.g. cmd.Flags().Int("port", 8080, "...")) before calling BindPFlag.
- Look up on the correct FlagSet — PersistentFlags() for inherited flags, Flags() for local.
Example fix
// before
v.BindPFlag("port", cmd.Flags().Lookup("port")) // -> flag for "port" is nil
// after
if f := cmd.Flags().Lookup("port"); f != nil {
_ = v.BindPFlag("port", f)
} else {
// flag not defined; register it or log the misconfiguration
} Defensive patterns
Strategy: type-guard
Validate before calling
func bindFlag(v *viper.Viper, key string, flags *pflag.FlagSet, name string) error {
f := flags.Lookup(name)
if f == nil {
return fmt.Errorf("flag %q not defined on the FlagSet", name)
}
return v.BindPFlag(key, f)
} Type guard
// nil-guard for *pflag.Flag before binding
func isFlagBoundable(f *pflag.Flag) bool { return f != nil }
// usage
if f := cmd.Flags().Lookup("port"); isFlagBoundable(f) {
_ = v.BindPFlag("port", f)
} Try / catch
if err := v.BindPFlag("port", cmd.Flags().Lookup("port")); err != nil {
if strings.Contains(err.Error(), "is nil") {
// flag not registered or looked up on the wrong FlagSet
}
} Prevention
- Always nil-check pflag FlagSet.Lookup results before binding.
- Register flags before any BindPFlag call (watch init() ordering).
- Look up inherited flags on PersistentFlags(), local ones on Flags().
When it happens
Trigger: v.BindPFlag("port", cmd.Flags().Lookup("port")) where 'port' was never added to cmd.Flags(); typo in the flag name; binding before the flag is registered; looking up on the wrong FlagSet (LocalFlags vs PersistentFlags).
Common situations: Cobra app where the flag lives on PersistentFlags but Lookup is called on LocalFlags; refactor that renamed a flag but left the old string in BindPFlag; binding inside an init() that runs before flag registration.
Related errors
AI-assisted analysis of spf13/viper@528f7416c4 (2026-08-04).
Data as JSON: /data/errors/21ab4f1ed30d0aac.json.
Report an issue: GitHub.