Skip to content

Fix Backstage App Config – Configuration Not Loading

DodaTech Updated 2026-06-24 2 min read

In this tutorial, you'll learn about Fix Backstage App Config. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

You edit app-config.yaml in your Backstage project, restart the dev server, and your changes aren't reflected. New integrations don't show up, the proxy target is still the old URL, or undefined appears where you expect env var values.

Wrong ❌

# app-config.yaml
app:
  title: My Backstage App
  baseUrl: http://localhost:3000

backend:
  baseUrl: http://localhost:7007
  listen:
    port: 7007

integrations:
  github:
    - host: github.com
      token: ${GITHUB_TOKEN}

You set GITHUB_TOKEN in your shell:

export GITHUB_TOKEN=ghp_abc123
yarn dev

But Backstage logs:

Error: Missing required config value at 'integrations.github[0].token'

Load environment variables correctly:

Backstage doesn't read arbitrary shell env vars. They must be defined in a .env file at the project root:

# .env
GITHUB_TOKEN=ghp_abc123

Or prefix with BACKSTAGE_:

export BACKSTAGE_GITHUB_TOKEN=ghp_abc123

Then reference in app-config.yaml as ${GITHUB_TOKEN} (without the BACKSTAGE_ prefix).

Check config schema:

If changes aren't picked up, Backstage validates config against a schema. Define optional config with $secret:

integrations:
  github:
    - host: github.com
      token:
        $secret:
          env: GITHUB_TOKEN

Re-build after changes:

yarn tsc && yarn build:backend
# Config changes are now compiled in

Verify config at runtime:

curl http://localhost:7007/api/config | jq .
{
  "app": {
    "title": "My Backstage App",
    "baseUrl": "http://localhost:3000"
  },
  "integrations": {
    "github": [{
      "host": "github.com",
      "token": "[REDACTED]"
    }]
  }
}

Root Cause

Backstage's config system loads app-config.yaml at compile time and validates it against a schema. Environment variables are only resolved if they're in a .env file or match the $secret schema syntax. Arbitrary shell env vars are ignored.

Prevention

  • Always use .env files for local development secrets.
  • Use the $secret schema pattern in app-config.yaml for all sensitive values.
  • Run yarn build:config:check to validate config before starting the backend.
  • Keep app-config.local.yaml for local overrides and add it to .gitignore.

Common Mistakes with app config

  1. Non-exhaustive pattern matches that compile with warnings then crash at runtime
  2. Misunderstanding that String is [Char] with poor performance for large text operations
  3. Using foldl instead of foldl' causing stack overflow on large lists

These mistakes appear frequently in real-world BACKSTAGE code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

**Q: How do I use different configs for dev vs production?**

A: Use app-config.yaml (shared) + app-config.production.yaml (loaded in production). Specify with APP_CONFIG_env prefix.

**Q: Why does backstage say "Config does not match schema"?**

A: Run yarn backstage-cli config:check to see which values are missing or extra. Fix the schema or config accordingly.

**Q: Can I use YAML anchors in app-config?**

A: Yes — Backstage uses standard YAML. Anchors (&, *) work for repetitive sections.

**Q: How do I debug which config file is loaded?**

A: Add --config flags to packages/backend/src/index.ts. Set LOG_LEVEL=debug to see config loading logs.


Backstage configuration is covered in the DodaTech Backstage Fundamentals course.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro