The FeatureGate registration mechanism within OpenTelemetry is failing, preventing new features from being enabled and causing the system to error out.

This usually happens because the FeatureGate system itself has a dependency that hasn’t initialized, or because the specific feature you’re trying to enable isn’t actually present in the build you’re running.

Common Causes and Fixes:

  1. Missing FeatureGate Initialization: The FeatureGate manager might not have been initialized before feature flags are checked.

    • Diagnosis: Look for logs indicating featuregate.NewManager() or similar initialization calls after feature gate checks. In your application code, find where featuregate.GlobalManager() is called or where featuregate.NewManager() is instantiated.
    • Fix: Ensure featuregate.NewManager() is called early in your application’s startup sequence, before any code attempts to check feature gates. For example, in main() or an init() function:
      import (
      	"go.opentelemetry.io/otel/sdk/featuregate"
      )
      
      func init() {
      	featuregate.SetGlobalManager(featuregate.NewManager())
      }
      
    • Why it works: This establishes a global, ready-to-use feature gate manager that subsequent checks can query.
  2. Incorrect Feature Gate Name: You’re trying to enable a feature using a name that doesn’t exist or is misspelled. Feature gate names are case-sensitive and often follow a specific convention (e.g., OTEL_Go_SDK_Tracer_Metric_Export).

    • Diagnosis: Double-check the exact name of the feature gate you are trying to enable against the OpenTelemetry SDK source code or documentation for the version you are using. Look for constants defined within go.opentelemetry.io/otel/sdk/featuregate/registry.go or similar files.
    • Fix: Correct the spelling and capitalization of the feature gate name in your configuration or environment variables. For example, if you intended to enable OTEL_Go_SDK_Native_Sampling but misspelled it as OTEL_Go_SDK_Native_Sample, fix it to the correct name.
    • Why it works: The system matches feature gate names exactly. A typo means the requested gate is never found, leading to the "not registered" error.
  3. Feature Gate Not Registered in the Build: The specific feature gate you’re trying to enable was removed, deprecated, or never included in the version of the OpenTelemetry SDK you’ve compiled or imported.

    • Diagnosis: Browse the OpenTelemetry Go SDK source code for the specific version you are using. Search for the feature gate constant. If it’s not there, it’s not available in that version. You can check the registry.go file in the sdk/featuregate package for a definitive list.
    • Fix:
      • Option A (Upgrade): If the feature gate is present in a newer version of the SDK, update your Go module dependencies to a version that includes it.
      • Option B (Remove): If the feature gate has been removed or deprecated, remove the configuration attempting to enable it.
    • Why it works: You can only enable features that are actually part of the code you are running. This fix ensures compatibility between your configuration and your SDK version.
  4. Conflicting Initialization Order in Libraries: If you’re using multiple libraries that also manage feature gates or have their own initialization logic, they might be interfering with OpenTelemetry’s FeatureGate initialization.

    • Diagnosis: Examine the init() functions of all imported packages. Look for any init() functions that might call featuregate.NewManager() or featuregate.SetGlobalManager() before the main OpenTelemetry SDK initialization happens.
    • Fix: Reorder your init() functions or move the OpenTelemetry FeatureGate initialization to be explicitly called before any other library that might also try to initialize it. Sometimes this involves creating a dedicated setup_otel.go file with an init() function that runs very early.
    • Why it works: Guarantees that the OpenTelemetry FeatureGate manager is the one that’s globally set and active, preventing others from overwriting it or being used before it’s ready.
  5. Environment Variable Overrides Not Applied Correctly: If you’re enabling feature gates via environment variables (e.g., OTEL_FEATURES), there might be an issue with how your application is reading or applying these variables.

    • Diagnosis: Print out the environment variables your application sees at startup. Verify that the OTEL_FEATURES variable (or any other relevant OTEL_ prefixed variable) is present and correctly formatted. For example, using os.Getenv("OTEL_FEATURES") in your Go code.
    • Fix: Ensure the environment variable is set before the OpenTelemetry SDK initializes. If running in a container, check your Dockerfile or Kubernetes deployment manifest. If running locally, ensure it’s set in your terminal session or .env file loaded by your framework.
      export OTEL_FEATURES="OTEL_Go_SDK_Native_Sampling=true"
      go run main.go
      
    • Why it works: The SDK reads these environment variables during its initialization phase to determine which features to enable. If the variable isn’t read, the features remain disabled.
  6. Custom Feature Gate Registry Not Properly Loaded: If you’ve implemented a custom featuregate.Manager or a custom registry, it might not be correctly registered or populated with the desired feature gates.

    • Diagnosis: Inspect the code responsible for creating and registering your custom featuregate.Manager. Ensure that featuregate.SetGlobalManager() is called with your custom manager, and that your custom manager correctly registers the feature gates it’s supposed to provide.
    • Fix: If using a custom manager, ensure it implements the featuregate.Manager interface correctly and that all intended feature gates are registered within its RegisterFeature calls.
      type myCustomManager struct {
      	featuregate.Manager
      }
      
      func (m *myCustomManager) RegisterFeature(id string, description string, enabledByDefault bool) {
      	// Your custom registration logic, or delegate to a base manager
      	m.Manager.RegisterFeature(id, description, enabledByDefault)
      }
      
      // In your init() or main()
      customManager := &myCustomManager{featuregate.NewManager()}
      customManager.RegisterFeature("MY_CUSTOM_FEATURE", "A special feature", true)
      featuregate.SetGlobalManager(customManager)
      
    • Why it works: This ensures that your specific, potentially extended, set of feature gates are available for the SDK to query.

The next error you’ll likely encounter after fixing FeatureGate issues is a NoOpSpan being created instead of a real span, indicating that tracing is not fully initialized or configured.

Want structured learning?

Take the full Opentelemetry course →