apache/pulsar · critical

config file is nil.

Error message

config file is nil.

What it means

newInstanceConf builds the Go function instance configuration from a YAML config file. If conf.GetConf() returns nil (viper failed to read/parse the config), the code panics with 'config file is nil.' because the instance cannot run without its configuration.

Solutions

  1. Ensure the config file path passed to the instance exists and is valid YAML before starting the function
  2. Verify environment variables/config injected by the runtime (e.g. conf file at /etc/pulsar/functions/config) are mounted
  3. Add a pre-flight check: load conf.Conf{}.GetConf() yourself and log viper errors instead of hitting the panic
  4. When running tests, construct the conf explicitly rather than relying on the default file lookup

Example fix

// before
ctx := pf.NewFuncContext() // panics: config file is nil.
// after
if cfg := (&conf.Conf{}).GetConf(); cfg == nil {
    log.Fatal("instance config missing: pass a valid config file path")
}
ctx := pf.NewFuncContext()
Defensive patterns

Strategy: validation

Validate before calling

cfg := (&conf.Conf{}).GetConf()
if cfg == nil {
    return fmt.Errorf("instance config file missing or invalid")
}

Type guard

func hasConfig() bool { return (&conf.Conf{}).GetConf() != nil }

Try / catch

// Go panics are not catchable idiomatic; pre-validate instead.
// If necessary: defer func() { if r := recover(); r != nil { log.Fatalf("config load failed: %v", r) } }()

Prevention

When it happens

Trigger: Calling pf.NewFuncContext (which calls newInstanceConf) when the config file path is wrong, the file does not exist, it is malformed YAML, or the environment (e.g. kubeless/function-mesh injector) failed to mount it.

Common situations: Running a Go function locally without the config file that production injects (functions_instance_config.conf), bad func.yaml config path, missing --instance-conf argument, or a k8s ConfigMap/volume mount miss.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/0230b5ada888cb45. Report an issue: GitHub.

Appendix: source

Thrown at pulsar-function-go/pf/instanceConf.go:158

	if !instanceConf.funcDetails.AutoAck && //nolint:staticcheck
		(instanceConf.funcDetails.ProcessingGuarantees == pb.ProcessingGuarantees_ATMOST_ONCE ||
			instanceConf.funcDetails.ProcessingGuarantees == pb.ProcessingGuarantees_ATLEAST_ONCE) {
		panic("When Guarantees == " + instanceConf.funcDetails.ProcessingGuarantees.String() +
			", autoAck must be equal to true. If you want not to automatically ack, " +
			"please configure the processing guarantees as MANUAL." +
			" This is a contradictory configuration, autoAck will be removed later." +
			" Please refer to PIP: https://github.com/apache/pulsar/issues/15560")
	}

	return instanceConf
}

func newInstanceConf() *instanceConf {
	config := &conf.Conf{}
	cfg := config.GetConf()
	if cfg == nil {
		panic("config file is nil.")
	}
	return newInstanceConfWithConf(cfg)
}

func (ic *instanceConf) getInstanceName() string {
	return "" + fmt.Sprintf("%d", ic.instanceID)
}

View on GitHub (pinned to 820761864e)