flagd Provider

The flagd provider connects to a flagd instance and evaluates feature flags in-process. Flag definitions are synced from flagd over gRPC and evaluated locally, so no network call is made during flag evaluation.

This extension depends on:

Component Version Source

flagd core

3.0.0

open-feature/java-sdk-contrib

Installation

<dependency>
    <groupId>io.quarkiverse.openfeature</groupId>
    <artifactId>quarkus-openfeature-flagd</artifactId>
    <version>1.0.0</version>
</dependency>

Configuration

By default, the provider connects to localhost:8015. To connect to a different flagd instance:

quarkus.openfeature.flagd.url=flagd.example.com:8015

For named domains:

quarkus.openfeature."experimentation".flagd.url=flagd-experiments.example.com:8015

The URL is normally a bare host:port; the default port is 8015. A scheme is accepted only in the two forms the provider implements, grpc:// for TCP and unix:// for a Unix domain socket. Anything else — including https://, and the gRPC name-resolver schemes dns://, xds:// and envoy:// — is rejected at startup.

A unix:// URL carries the absolute socket path, so it takes three slashes: unix:///var/run/flagd.sock. Anything else, such as unix://flagd.sock, is rejected at startup.

A unix:// URL needs a Vert.x native transport, which is not enabled by default. Set quarkus.vertx.prefer-native-transport=true and add a dependency on io.netty:netty-transport-native-epoll (classifier derived from your OS and platform, for example linux-x86_64); without both, the application fails to start with a message saying so.

TLS

The provider uses the Quarkus TLS registry for TLS configuration. First, configure a named TLS configuration in application.properties, then reference it:

quarkus.tls.flagd.trust-store.pem.certs=ca.pem

quarkus.openfeature.flagd.tls-configuration-name=flagd

See the Quarkus TLS registry documentation for all available options.

Authentication

The flagd sync protocol does not define an authentication mechanism. To secure the connection, use TLS and network-level controls.

Offline mode

For testing or development without a running flagd instance, the provider can read flags from a local JSON file:

quarkus.openfeature.flagd.offline-path=/path/to/flags.json

In offline mode, no gRPC connection is made, Dev Services do not start a flagd container, and flag values are static. The file is read once, while the provider is created, and offline mode never retries: nothing would read the file again for the life of the process. A file that is missing or does not parse is therefore a misconfiguration and not a connection failure, and it fails the application startup.

Selector

If your flagd instance serves multiple flag sources, you can use a selector to filter to a specific one:

quarkus.openfeature.flagd.selector=flagSetId=my-flags

Provider ID

To identify this client to the flagd server:

quarkus.openfeature.flagd.provider-id=my-service

The server may use this ID to uniquely identify the client, for example in telemetry, and filter flag configurations that it can expose to the client.

Note that this value is sent in the gRPC request for synchronization and is not related to flagd providers.

Evaluation context

The evaluation context is passed directly to the flagd evaluation engine for use in targeting rules.

Dev Services

In dev and test mode, a flagd container is started automatically if no quarkus.openfeature.flagd.url is configured and Docker is available. If no flag definition file is found, flagd starts with an empty configuration.

To provide flag definitions to the dev service, place a flags.json file in src/main/resources:

{
  "flags": {
    "welcome-banner": {
      "state": "ENABLED",
      "variants": {
        "on": true,
        "off": false
      },
      "defaultVariant": "on"
    }
  }
}
See the flag definitions reference for the complete format.

The dev service picks up this file automatically. You can also configure a different path:

quarkus.openfeature.flagd.devservices.path=my-flags.json

Changes to the flag definition file are detected during live reload and the application is restarted automatically. The flagd container picks up the updated file through its own file watcher.

Connection lifecycle

The provider maintains a persistent gRPC streaming connection to flagd. On connection loss, it automatically attempts to reconnect. The provider lifecycle follows the OpenFeature specification:

READY

The provider has received flag data and is serving evaluations.

STALE

The connection was lost. The provider continues serving cached flag values while reconnecting.

ERROR

The provider did not reconnect within the grace period (default 1 minute).

FATAL

The server returned a fatal gRPC status (such as PERMISSION_DENIED or UNAUTHENTICATED). The provider will not attempt to reconnect.

The grace period is configurable:

quarkus.openfeature.flagd.grace-period=10m

A connection that is dropped silently somewhere in transit cannot be noticed from the stream alone. Therefore, a stream that has not delivered any data for configurable amount of time is closed, which triggers a reconnect:

quarkus.openfeature.flagd.stream-deadline=5m

The whole flag configuration arrives as a single gRPC message, whose size is capped at 4 MB by default. A larger message is rejected and the stream reconnects, so a server that keeps sending one never becomes READY. To raise the limit:

quarkus.openfeature.flagd.max-configuration-size=8M

Configuration Reference

Configuration property fixed at build time - All other configuration properties are overridable at runtime

Configuration property

Type

Default

quarkus.openfeature."domain-name".flagd.devservices.enabled

If DevServices has been explicitly enabled or disabled. DevServices is generally enabled by default, unless there is an existing configuration present.

When DevServices is enabled Quarkus will attempt to automatically configure and start a flagd instance when running in Dev or Test mode and when Docker is running.

Environment variable: QUARKUS_OPENFEATURE_FLAGD_DEVSERVICES_ENABLED

boolean

true

quarkus.openfeature."domain-name".flagd.devservices.image-name

The container image name to use, for container based DevServices providers.

Environment variable: QUARKUS_OPENFEATURE_FLAGD_DEVSERVICES_IMAGE_NAME

string

ghcr.io/open-feature/flagd:latest

quarkus.openfeature."domain-name".flagd.devservices.port

Optional fixed port the dev service will listen to.

If not defined, the port will be chosen randomly.

Environment variable: QUARKUS_OPENFEATURE_FLAGD_DEVSERVICES_PORT

int

quarkus.openfeature."domain-name".flagd.devservices.path

Path to a flag definition file on the classpath. If not configured explicitly and the default flags.json file does not exist, flagd starts with an empty flag configuration. If configured explicitly and the file does not exist, the build fails.

Environment variable: QUARKUS_OPENFEATURE_FLAGD_DEVSERVICES_PATH

string

flags.json

quarkus.openfeature."domain-name".flagd.devservices.shared

Indicates if the flagd instance managed by Quarkus Dev Services is shared. When shared, Quarkus looks for running containers using label-based service discovery. If a matching container is found, it is used, and so a second one is not started. Otherwise, Dev Services for flagd starts a new container.

The discovery uses the quarkus-dev-service-flagd label. The value is configured using the service-name property.

Container sharing is only used in dev mode.

Environment variable: QUARKUS_OPENFEATURE_FLAGD_DEVSERVICES_SHARED

boolean

true

quarkus.openfeature."domain-name".flagd.devservices.service-name

The value of the quarkus-dev-service-flagd label attached to the started container. This property is used when shared is set to true. In this case, before starting a container, Dev Services for flagd looks for a container with the quarkus-dev-service-flagd label set to the configured value. If found, it will use this container instead of starting a new one. Otherwise, it starts a new container with the quarkus-dev-service-flagd label set to the specified value.

This property is used when you need multiple shared flagd servers.

Environment variable: QUARKUS_OPENFEATURE_FLAGD_DEVSERVICES_SERVICE_NAME

string

flagd

quarkus.openfeature."domain-name".flagd.url

flagd server URL, normally a bare host:port with 8015 as the default port. The only accepted schemes are grpc:// and unix:// (a Unix domain socket, whose path must be absolute, as in unix:///var/run/flagd.sock); anything else, https:// included, is rejected at startup. The scheme does not control TLS; use tls-configuration-name() for that.

Environment variable: QUARKUS_OPENFEATURE_FLAGD_URL

string

localhost:8015

quarkus.openfeature."domain-name".flagd.tls-configuration-name

TLS configuration name from the Quarkus TLS registry.

Environment variable: QUARKUS_OPENFEATURE_FLAGD_TLS_CONFIGURATION_NAME

string

quarkus.openfeature."domain-name".flagd.stream-deadline

Idle timeout for the gRPC streaming connection. If no data is received within this period, the stream is closed and a reconnect is attempted.

Environment variable: QUARKUS_OPENFEATURE_FLAGD_STREAM_DEADLINE

Duration 

10M

quarkus.openfeature."domain-name".flagd.max-configuration-size

Maximum size of a single flag configuration received from flagd. The whole configuration arrives as one gRPC message, so this is effectively the limit on how many flags the server may serve; a larger message is rejected and the stream is reconnected.

Environment variable: QUARKUS_OPENFEATURE_FLAGD_MAX_CONFIGURATION_SIZE

MemorySize 

4M

quarkus.openfeature."domain-name".flagd.grace-period

Grace period before transitioning from STALE to ERROR after a connection loss. During this period, the provider continues serving cached flag values while attempting to reconnect. If the connection is restored within the grace period, the provider transitions back to READY without emitting an ERROR event.

Environment variable: QUARKUS_OPENFEATURE_FLAGD_GRACE_PERIOD

Duration 

1M

quarkus.openfeature."domain-name".flagd.provider-id

Unique identifier for this client, sent to flagd for telemetry, monitoring, and routing purposes.

Environment variable: QUARKUS_OPENFEATURE_FLAGD_PROVIDER_ID

string

quarkus.openfeature."domain-name".flagd.selector

Selector for filtering which flag source to sync when flagd serves multiple flag sources.

Environment variable: QUARKUS_OPENFEATURE_FLAGD_SELECTOR

string

quarkus.openfeature."domain-name".flagd.offline-path

Path to a JSON flag definition file for offline mode. When set, the provider reads flags from this file instead of connecting to a flagd instance.

Environment variable: QUARKUS_OPENFEATURE_FLAGD_OFFLINE_PATH

string

quarkus.openfeature."domain-name".flagd.use-quarkus-jackson

Whether to use the Quarkus-managed ObjectMapper from the quarkus-jackson extension. When false, the provider creates its own ObjectMapper instance.

Environment variable: QUARKUS_OPENFEATURE_FLAGD_USE_QUARKUS_JACKSON

boolean

true

About the Duration format

To write duration values, use the standard java.time.Duration format. See the Duration#parse() Java API documentation for more information.

You can also use a simplified format, starting with a number:

  • If the value is only a number, it represents time in seconds.

  • If the value is a number followed by ms, it represents time in milliseconds.

In other cases, the simplified format is translated to the java.time.Duration format for parsing:

  • If the value is a number followed by h, m, or s, it is prefixed with PT.

  • If the value is a number followed by d, it is prefixed with P.

About the MemorySize format

A size configuration option recognizes strings in this format (shown as a regular expression): [0-9]+[KkMmGgTtPpEeZzYy]?.

If no suffix is given, assume bytes.