{"record":{"id":"ae717ea33f73ef84","repo":"grpc/grpc-go","slug":"error-reading-observability-configuration-file-q","errorCode":null,"errorMessage":"error reading observability configuration file %q: %v","messagePattern":"error reading observability configuration file %q: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gcp/observability/config.go","lineNumber":133,"sourceCode":"\t}\n\tif err := validateLoggingEvents(&config); err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing observability config: %v\", err)\n\t}\n\tif config.CloudTrace != nil && (config.CloudTrace.SamplingRate > 1 || config.CloudTrace.SamplingRate < 0) {\n\t\treturn nil, fmt.Errorf(\"error parsing observability config: invalid cloud trace sampling rate %v\", config.CloudTrace.SamplingRate)\n\t}\n\tlogger.Infof(\"Parsed ObservabilityConfig: %+v\", &config)\n\treturn &config, nil\n}\n\nfunc parseObservabilityConfig() (*config, error) {\n\tif f := envconfig.ObservabilityConfigFile; f != \"\" {\n\t\tif envconfig.ObservabilityConfig != \"\" {\n\t\t\tlogger.Warning(\"Ignoring GRPC_GCP_OBSERVABILITY_CONFIG and using GRPC_GCP_OBSERVABILITY_CONFIG_FILE contents.\")\n\t\t}\n\t\tcontent, err := os.ReadFile(f)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error reading observability configuration file %q: %v\", f, err)\n\t\t}\n\t\treturn unmarshalAndVerifyConfig(content)\n\t} else if envconfig.ObservabilityConfig != \"\" {\n\t\treturn unmarshalAndVerifyConfig([]byte(envconfig.ObservabilityConfig))\n\t}\n\t// If the ENV var doesn't exist, do nothing\n\treturn nil, nil\n}\n\nfunc ensureProjectIDInObservabilityConfig(ctx context.Context, config *config) error {\n\tif config.ProjectID == \"\" {\n\t\t// Try to fetch the GCP project id\n\t\tprojectID := fetchDefaultProjectID(ctx)\n\t\tif projectID == \"\" {\n\t\t\treturn fmt.Errorf(\"empty destination project ID\")\n\t\t}\n\t\tconfig.ProjectID = projectID\n\t}","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/gcp/observability/config.go#L115-L151","documentation":"parseObservabilityConfig reads the file at GRPC_GCP_OBSERVABILITY_CONFIG_FILE and os.ReadFile returned an error (the message includes the path and the OS error). This fires before any JSON parsing, so the file is missing, unreadable, or the path is wrong. When this env var is set, it takes precedence over GRPC_GCP_OBSERVABILITY_CONFIG.","triggerScenarios":"GRPC_GCP_OBSERVABILITY_CONFIG_FILE points to a path that does not exist, is a directory, or has restrictive permissions; the env var was set to a relative path but the process's working directory differs.","commonSituations":"Kubernetes ConfigMap mount path mistyped; file mounted read-only to a different UID; relative path used in a container whose CWD is /; dangling symlink.","solutions":["Verify the path exists and is readable by the process: `ls -l <path>` and `cat <path>` from inside the container.","Use an absolute path for the env var; ensure ConfigMap/Secret mounts land at that exact path.","If you meant to use the inline env var instead, unset GRPC_GCP_OBSERVABILITY_CONFIG_FILE and set GRPC_GCP_OBSERVABILITY_CONFIG."],"exampleFix":"# before\nexport GRPC_GCP_OBSERVABILITY_CONFIG_FILE=/etc/grpc/obs.yaml\n# (file is YAML, missing, or wrong path)\n\n# after\nexport GRPC_GCP_OBSERVABILITY_CONFIG_FILE=/etc/grpc/obs.json\n# ensure /etc/grpc/obs.json exists, is JSON, and is world-readable","handlingStrategy":"validation","validationCode":"func readableObservabilityConfigFile(path string) error {\n    info, err := os.Stat(path)\n    if err != nil { return err }\n    if info.IsDir() { return errors.New(\"path is a directory\") }\n    if info.Mode().Perm()&0400 == 0 { return errors.New(\"file not readable\") }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"content, err := os.ReadFile(path)\nif err != nil { return fmt.Errorf(\"read obs config %s: %w\", path, err) }","preventionTips":["Use an absolute path for GRPC_GCP_OBSERVABILITY_CONFIG_FILE.","Mount the config via ConfigMap/Secret at a known absolute path and verify permissions.","To use inline config instead, unset *_FILE and set GRPC_GCP_OBSERVABILITY_CONFIG."],"tags":["grpc","observability","config","filesystem","env","gcp"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}