GoogleCloudPlatform/microservices-demo · critical · Exception

PRODUCT_CATALOG_SERVICE_ADDR environment variable not set

Error message

PRODUCT_CATALOG_SERVICE_ADDR environment variable not set

What it means

The recommendationservice startup requires PRODUCT_CATALOG_SERVICE_ADDR to know where the product catalog gRPC service lives. If the environment variable is empty or unset, it raises a bare Exception and the server exits before binding its gRPC port. It is a deliberate fail-fast configuration check.

Source

Thrown at src/recommendationservice/recommendation_server.py:133

        trace.set_tracer_provider(TracerProvider())
        otel_endpoint = os.getenv("COLLECTOR_SERVICE_ADDR", "localhost:4317")
        trace.get_tracer_provider().add_span_processor(
          BatchSpanProcessor(
              OTLPSpanExporter(
              endpoint = otel_endpoint,
              insecure = True
            )
          )
        )
    except (KeyError, DefaultCredentialsError):
        logger.info("Tracing disabled.")
    except Exception as e:
        logger.warn(f"Exception on Cloud Trace setup: {traceback.format_exc()}, tracing disabled.") 

    port = os.environ.get('PORT', "8080")
    catalog_addr = os.environ.get('PRODUCT_CATALOG_SERVICE_ADDR', '')
    if catalog_addr == "":
        raise Exception('PRODUCT_CATALOG_SERVICE_ADDR environment variable not set')
    logger.info("product catalog address: " + catalog_addr)
    channel = grpc.insecure_channel(catalog_addr)
    product_catalog_stub = demo_pb2_grpc.ProductCatalogServiceStub(channel)

    # create gRPC server
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))

    # add class to gRPC server
    service = RecommendationService()
    demo_pb2_grpc.add_RecommendationServiceServicer_to_server(service, server)
    health_pb2_grpc.add_HealthServicer_to_server(service, server)

    # start server
    logger.info("listening on port: " + port)
    server.add_insecure_port('[::]:'+port)
    server.start()

    # keep alive

View on GitHub (pinned to 72ba613a05)

Solutions

  1. Set PRODUCT_CATALOG_SERVICE_ADDR before starting, e.g. export PRODUCT_CATALOG_SERVICE_ADDR=productcatalogservice:3550
  2. In Kubernetes, add the env var (or use ConfigMap/envFrom) to the recommendationservice deployment
  3. In docker run/compose, pass -e PRODUCT_CATALOG_SERVICE_ADDR=<host>:<port>
  4. Verify the service name resolves (DNS) once the variable is set

Example fix

# before
python recommendation_server.py
# after
export PRODUCT_CATALOG_SERVICE_ADDR=productcatalogservice:3550 && python recommendation_server.py
Defensive patterns

Strategy: validation

Validate before calling

import os
addr = os.environ.get('PRODUCT_CATALOG_SERVICE_ADDR')
if not addr:
    raise SystemExit("Set PRODUCT_CATALOG_SERVICE_ADDR (e.g. productcatalogservice:3550) before starting")
# then start: PRODUCT_CATALOG_SERVICE_ADDR=productcatalogservice:3550 python recommendation_server.py

Try / catch

try:
    main()
except Exception as e:
    if 'PRODUCT_CATALOG_SERVICE_ADDR' in str(e):
        print('Missing required env var PRODUCT_CATALOG_SERVICE_ADDR')
        sys.exit(1)
    raise

Prevention

When it happens

Trigger: Starting recommendation_server.py (main) without PRODUCT_CATALOG_SERVICE_ADDR in the environment, e.g. running the container manually without the env var, or a Kubernetes/compose manifest missing the env entry.

Common situations: Local `python recommendation_server.py` runs where k8s normally injects the env var; docker run without -e PRODUCT_CATALOG_SERVICE_ADDR=productcatalogservice:3550; typos in deployment YAML env names.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of GoogleCloudPlatform/microservices-demo@72ba613a05 (2026-09-02). Data as JSON: /api/errors/15a97e0ad2989820. Report an issue: GitHub.