When a Java application sends traces to an observability platform, the results do not always match what you expect. Some requests may be missing, service names may be incorrect, or traces may never reach the configured backend.
In many cases, the problem is not in the application code. It comes from the OpenTelemetry Java agent configuration, environment variables, sampling rules, or exporter settings.
The Java agent can collect telemetry without requiring developers to add tracing code to every application. However, it also means that configuration must be checked carefully, especially when an application runs in Docker, Kubernetes, or a CI/CD environment.
This article explains how to inspect the OpenTelemetry Java agent configuration, identify which settings are active, and troubleshoot missing or unexpected traces.
How the OpenTelemetry Java Agent Works
The OpenTelemetry Java agent attaches to a Java application when the JVM starts. It uses instrumentation to collect telemetry from supported libraries and frameworks, including HTTP servers, HTTP clients, and database drivers.
The agent can create spans, attach attributes, propagate trace context, and export telemetry to a configured destination.
A typical startup command looks like this:
java -javaagent:/opt/otel/opentelemetry-javaagent.jar \
-jar application.jarThe agent is loaded before the application starts. Its behavior can be controlled through Java system properties, environment variables, and an optional configuration file.
For example, the agent may use one service name locally and another in a container because the environments provide different configuration values.
Understanding where those values come from is the first step toward troubleshooting tracing problems.
Step 1: Check the Java Agent Startup Configuration
Start by confirming that the Java agent is actually attached to the application.
Check the command used to start the JVM. Look for the Java agent argument and verify that the JAR path points to the expected file.
For example:
java -javaagent:/opt/otel/opentelemetry-javaagent.jar \
-Dotel.service.name=order-service \
-jar application.jarIn this example, the agent is loaded from the specified path, and the service name is set through a Java system property.
If the application is started by a shell script, container entry point, process manager, or deployment platform, inspect the actual startup command rather than relying only on the command documented in the repository.
A common problem occurs when a deployment uses a different startup script from the one tested locally.
You should also check the application startup logs for messages from the OpenTelemetry Java agent. These can help confirm that the agent initialized successfully and reveal configuration or instrumentation errors.
Step 2: Inspect Environment Variables and Java Properties
The Java agent supports several configuration methods. Two common options are environment variables and Java system properties.
Consider the following environment variables:
export OTEL_SERVICE_NAME=order-service
export OTEL_TRACES_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
export OTEL_RESOURCE_ATTRIBUTES=deployment.environment=developmentThese settings configure the service name, trace exporter, OTLP endpoint, and an additional resource attribute.
The endpoint shown here is an example for an OTLP HTTP endpoint. If your collector expects OTLP over gRPC, the endpoint and protocol configuration must match that setup.
The same service name can be configured using a Java system property:
java -javaagent:/opt/otel/opentelemetry-javaagent.jar \
-Dotel.service.name=order-service \
-jar application.jarWhen the same property is configured in multiple places, the effective value depends on the configuration mechanism and its precedence rules. Java system properties generally take precedence over environment variables for the standard OpenTelemetry configuration properties.
Do not assume that changing an environment variable will change the active configuration if a higher-precedence system property is also set.
Check the configuration in your deployment environment
For a local process, inspect the environment used to launch the application. For Docker or Kubernetes, inspect the container configuration and the actual Java startup arguments.
For example, on Linux, you can inspect a running process with:
ps -ef | grep '[j]ava'This can help reveal the Java command-line arguments, including system properties and the agent path. It does not show every environment variable or prove which configuration the agent ultimately accepted.
Avoid printing secrets or sensitive environment variables into build logs or support tickets.
Step 3: Check the Service Name and Resource Attributes
A trace may reach the observability backend but appear under an unexpected service name.
The service name identifies the application that produced the telemetry. Resource attributes provide additional information about that application and its execution environment.
For example:
export OTEL_SERVICE_NAME=payment-service
export OTEL_RESOURCE_ATTRIBUTES=deployment.environment=staging,service.version=2.4.0The application should now report the configured service name and the specified resource attributes, assuming no higher-precedence configuration overrides them.
If the service appears under the wrong name, check the following:
The OTEL_SERVICE_NAME environment variable.
The corresponding Java system property, if one is set.
The resource attributes configured through other mechanisms.
The startup configuration used by the actual running process.
Any application-specific OpenTelemetry SDK configuration.
Do not confuse resource attributes with span attributes. Resource attributes describe the entity producing telemetry, while span attributes describe a particular operation.
Keeping service names and environment attributes consistent makes it easier to filter traces and compare behavior across deployments.
Step 4: Check Sampling Settings
Sampling determines which traces are recorded and exported. This is an important setting when only some requests appear in your tracing backend.
The Java agent supports configuration through properties such as:
export OTEL_TRACES_SAMPLER=parentbased_traceidratio
export OTEL_TRACES_SAMPLER_ARG=0.25This configures a parent-based sampler with a trace ID ratio of 0.25. For root traces, the ratio-based sampler aims to sample approximately 25 percent of traces. Child spans generally follow the sampling decision of their parent.
This does not guarantee that exactly 25 percent of requests will appear in every short test run.
For a controlled local investigation, you can temporarily use an always-on sampler:
export OTEL_TRACES_SAMPLER=always_onThis helps determine whether sampling is responsible for missing traces. Use it carefully in production because recording every trace can significantly increase telemetry volume.
If traces are still missing, investigate instrumentation, export failures, collector configuration, and backend filtering rather than assuming sampling is the only cause.
Step 5: Verify the Exporter and Endpoint
The agent needs a working exporter configuration to send traces to the intended destination.
For an OTLP HTTP setup, a configuration might look like this:
export OTEL_TRACES_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318The endpoint must match the collector's configuration and network location.
A common mistake is using an endpoint that is correct on the developer's machine but incorrect inside a container. In a container, localhost refers to that container itself, not automatically to the host machine or another container.
Check the following when traces do not arrive:
Is the collector running?
Is the configured endpoint reachable from the application?
Does the collector accept the selected protocol?
Are the expected ports exposed and accessible?
Does the collector accept and forward the received telemetry?
Is the backend querying the correct service and time range?
If the exporter reports connection errors, investigate network access and collector availability first.
Step 6: Enable Agent Debug Logging
When the configuration still looks correct but traces are missing, enable the Java agent's debug logging in a controlled environment.
You can use the following setting:
export OTEL_JAVAAGENT_DEBUG=trueRestart the application after setting the variable so the agent starts with the new configuration.
The resulting logs can provide additional information about agent initialization, instrumentation, and configuration-related problems. The exact messages depend on the agent version and the issue being investigated.
Debug logging can generate a large amount of output. Enable it temporarily, collect the relevant startup and error messages, and turn it off when the investigation is complete.
Do not assume that debug logging will print every effective configuration value or expose every reason a trace is absent. Use it alongside startup arguments, deployment settings, exporter diagnostics, and collector logs.
Step 7: Check Configuration Files and Deployment Overrides
For larger deployments, you may want to keep agent settings in a dedicated configuration file.
The Java agent supports a configuration file through the OTEL_JAVAAGENT_CONFIGURATION_FILE setting.
For example:
export OTEL_JAVAAGENT_CONFIGURATION_FILE=/etc/otel/java-agent.propertiesThe file can contain agent properties such as:
otel.service.name=order-service
otel.traces.exporter=otlp
otel.traces.sampler=parentbased_traceidratio
otel.traces.sampler.arg=0.25Make sure the file exists, is readable by the application process, and contains valid property names and values.
If environment variables, Java properties, and a configuration file all define the same setting, verify which source takes precedence for the configuration option in question. Avoid maintaining conflicting values across several locations.
In Kubernetes, also check the Deployment configuration, ConfigMaps, Secrets, and startup arguments. The configuration in the repository may not match what the running pod actually receives.
Common Problems and Solutions
Problem | Possible cause | What to check |
|---|---|---|
No traces appear | Agent not attached or export failure | JVM startup command and agent logs |
Only some traces appear | Sampling configuration | Sampler name and sampling argument |
Wrong service name | Conflicting configuration | System properties, environment variables, and configuration file |
Export connection fails | Incorrect endpoint or protocol | Collector address, port, and protocol |
Traces appear locally but not in a container | Different network or environment configuration | Container environment and service discovery |
HTTP spans are missing | Unsupported or disabled instrumentation | Agent version and instrumentation configuration |
Custom spans are missing | Custom instrumentation is not registered or exported | Activity or span source configuration and SDK setup |
Best Practices for Managing Agent Settings
Keep tracing configuration in a documented, predictable location. If your team uses environment variables in production and a configuration file for local development, define which settings belong in each location.
Record the agent version and relevant non-sensitive configuration details during troubleshooting. This helps distinguish configuration changes from changes introduced by an agent upgrade.
Use consistent service names and resource attributes across environments. Test sampling and exporter changes before deploying them broadly.
Finally, verify the complete telemetry path. A Java agent can create spans successfully while the collector or backend still fails to receive or display them.
Advantages and Limitations
The OpenTelemetry Java agent reduces the need to modify application code for common instrumentation. Its configurable behavior also makes it useful across different deployment environments.
However, configuration can become difficult to track when values are spread across environment variables, system properties, configuration files, and deployment manifests. Automatic instrumentation also cannot provide every business-specific span or guarantee that all traces will be sampled and exported.
For reliable results, combine agent configuration checks with application-level instrumentation, collector monitoring, and repeatable tracing tests.
Summary
When OpenTelemetry traces are missing or contain unexpected information, start by checking the Java agent startup command and the configuration sources used by the running application.
Verify the service name, resource attributes, sampling settings, exporter protocol, and endpoint. If the problem remains unclear, enable agent debug logging temporarily and inspect the collector's logs.
The most important step is to check the entire telemetry path instead of changing settings at random. A consistent configuration and a repeatable troubleshooting process make Java tracing problems easier to diagnose across local, containerized, and production environments.

Join the conversation! Your thoughts help the community grow.