How to Fix Azure SDK for Java Setup & Config Errors
Why This Is Happening
I've seen this exact situation play out on dozens of developer machines: you're trying to get your Java application talking to Azure services , maybe Blob Storage, Key Vault, or Service Bus , and somewhere between the first pom.xml edit and the first actual API call, things go sideways. Build failures. Dependency conflicts. A cryptic error that just says "could not resolve artifact" with a version string that makes no sense. You Google it, find a three-year-old Stack Overflow thread, copy a snippet, and now you have two problems.
Here's the honest truth: the Azure SDK for Java has gone through significant architectural changes over the years. Microsoft ships what they call "current generation" libraries, the azure-* packages, alongside older "previous generation" ones. If your project accidentally mixes both, you'll get confusing runtime errors and dependency resolution nightmares that have nothing to do with your actual code. The error messages from Maven rarely point at the real culprit, which makes this especially maddening.
The other common trap is manual version pinning. Developers add an Azure client library, manually specify a version in the POM, and then six months later a colleague adds a second Azure library with a different manually pinned version. Those two libraries pull in overlapping transitive dependencies at conflicting versions, and suddenly your build is broken in ways that seem completely unrelated to anything Azure. This is precisely the problem that Microsoft's Bill of Materials (BOM) pattern, specifically the azure-sdk-bom, was designed to eliminate, but a lot of developers don't know it exists or don't use it correctly.
There's also the Java version mismatch issue. The Azure SDK for Java supports JDK 8 and later, but Microsoft recommends version 17 for the best experience. If you're on an older JDK, certain features behave differently, GraalVM native image compilation may fail outright, and some newer authentication flows have subtle compatibility gaps. The archetype defaults to the latest LTS release (currently 17) for good reason.
Finally, there's the setup-from-scratch problem. Most documentation assumes you already have a working Maven project. But if you're starting fresh and want things wired up correctly from day one, with BOM alignment, build tool integration, and optional GraalVM support, knowing where to even begin isn't obvious. That's exactly what we'll fix here.
Whether you're getting BUILD FAILURE errors on your first compile, hitting authentication issues because your SDK versions are mismatched, or just trying to understand why your Azure SDK project doesn't follow the best practices Microsoft recommends, you're in the right place. Browse all Microsoft fix guides →
The Quick Fix, Try This First
If you're starting a new project and want everything configured correctly without manually wiring up dependencies, the fastest path is Microsoft's own Maven archetype. This generates a project skeleton that already includes the azure-sdk-bom, optional GraalVM native image support, and the Azure SDK build tool, all pre-configured and aligned.
Open a terminal in the directory where you want your project to live. You need Apache Maven installed and a JDK 8 or later on your PATH (JDK 17 is strongly recommended). Run this single command:
mvn archetype:generate \
-DarchetypeGroupId=com.azure.tools \
-DarchetypeArtifactId=azure-sdk-archetype
Maven will reach out to Maven Central, pull the archetype, and then prompt you interactively for a handful of project details. Here's what each prompt is asking:
- groupId, your organization's reverse-domain identifier, like
com.mycompany. This is required. - artifactId, the name of your project/module, like
my-azure-app. Also required. - package, the Java package for generated source files. If you skip it, Maven infers it from your groupId.
- azureLibraries, a comma-separated list of Azure SDK Maven artifact IDs you want pre-wired, like
azure-storage-blob,azure-identity. Leave blank if you'll add them manually later. - javaVersion, the minimum JDK version to target. Defaults to 17. You can set it to 8, 11, or 17.
- junitVersion, 4 or 5. Defaults to 5 (JUnit Jupiter). Most modern projects should stay on 5.
- enableGraalVM, true or false. Defaults to true, which adds the native image plugin. If you don't need native binary compilation, you can set this to false to keep the POM simpler.
After answering the prompts, Maven generates a complete project directory. Open it in IntelliJ IDEA or Eclipse, both have first-class Maven support, and run mvn compile to verify everything resolves cleanly. If your build succeeds on the first try, your Azure SDK for Java project is correctly bootstrapped and you can skip straight to adding your application logic.
If you need to automate project generation (say, in a CI pipeline or an internal scaffolding script), you can pass all the values inline without interactive prompts:
mvn archetype:generate \
-DarchetypeGroupId=com.azure.tools \
-DarchetypeArtifactId=azure-sdk-archetype \
-DgroupId=com.mycompany \
-DartifactId=my-azure-app \
-DjavaVersion=17 \
-DenableGraalVM=false \
-DjunitVersion=5 \
-DinteractiveMode=false
azure-sdk-bom to your POM's <dependencyManagement> block. This single change fixes the majority of version conflict errors without touching any of your existing dependency declarations.
I can't count how many Azure SDK for Java build failures I've traced back to a broken local environment rather than any SDK issue at all. Before you touch a single line of XML, confirm your tools are actually what you think they are.
Run both of these in a fresh terminal window:
java -version
mvn -version
For Java, you want to see version 8 or later, but seriously, use 17. Microsoft says it outright: JDK 17 gives you the best experience. If you're on JDK 8 or 11, you may hit edge cases with async APIs and authentication flows that simply don't reproduce on 17. If you need to manage multiple JDK versions, consider SDKMAN on Linux/macOS or the Microsoft Build of OpenJDK on Windows.
For Maven, you want 3.6 or later. The archetype and the Azure SDK build tool both expect a reasonably modern Maven. Older versions sometimes fail to resolve BOM imports correctly.
Also check that JAVA_HOME is set and points at the right JDK. Maven reads JAVA_HOME to decide which JDK to use for compilation, even if your java -version command shows the right version, a stale JAVA_HOME can point Maven at a completely different JDK:
# On Linux/macOS
echo $JAVA_HOME
# On Windows (Command Prompt)
echo %JAVA_HOME%
# On Windows (PowerShell)
$env:JAVA_HOME
If JAVA_HOME is blank or pointing at the wrong path, fix it before proceeding. Once both commands show the right versions and JAVA_HOME is correct, you have a solid foundation. Move on to setting up your project structure.
This step is the single most impactful fix for Azure SDK for Java dependency conflicts. The Bill of Materials (BOM) is a special POM artifact that declares aligned, compatible versions for every Azure SDK for Java library. When you import it into your project's <dependencyManagement> section, you stop specifying versions on individual Azure dependencies entirely, the BOM handles it.
If you used the archetype, this is already done. If you're adding the SDK to an existing project, open your pom.xml and add the following block. Find the latest BOM version on Maven Central by searching for azure-sdk-bom:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-sdk-bom</artifactId>
<version>{latest_version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Once that's in place, add your individual Azure client libraries in the regular <dependencies> block, but without a version tag:
<dependencies>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-storage-blob</artifactId>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
</dependency>
</dependencies>
Maven will resolve the correct versions from the BOM. If you already have Azure dependencies with manually pinned versions, remove those version tags now. The Azure SDK build tool (covered in Step 3) will actually flag manually overridden versions as a policy violation, which is your safety net going forward.
Run mvn dependency:tree after this change. If you see Azure SDK artifacts resolving without version conflicts, the BOM is working correctly.
Microsoft ships a Maven build plugin, the Azure SDK build tool, that analyzes your project at compile time and catches configuration problems before they turn into runtime failures. Think of it as a linter specifically for Azure SDK usage. It runs locally and, by default, sends a build report to Microsoft for telemetry (you can turn this off if that's a concern for your organization).
Add it to the <build><plugins> section of your pom.xml. Replace {latest_version} with the current version from Maven Central:
<build>
<plugins>
<plugin>
<groupId>com.azure.tools</groupId>
<artifactId>azure-sdk-build-tool</artifactId>
<version>{latest_version}</version>
</plugin>
</plugins>
</build>
To run it:
mvn compile azure:run
The tool checks several things by default: that your BOM import is present and points at the latest version, that no Azure dependencies have manually overridden versions, and that you're not using deprecated previous-generation Azure libraries alongside current ones. It also flags usage of methods annotated with @Beta in GA releases, these are APIs that haven't been stabilized yet and may change.
You can customize what the tool checks by adding a <configuration> block. For example, if your team has a policy against beta library usage, turn on that check explicitly:
<configuration>
<validateNoBetaLibraryUsed>true</validateNoBetaLibraryUsed>
<sendToMicrosoft>false</sendToMicrosoft>
<reportFile>${project.build.directory}/azure-sdk-report.json</reportFile>
</configuration>
Setting reportFile writes a JSON report to your build target directory instead of just printing to the terminal, that output is much easier to parse in CI environments. Wire this into your pipeline and you'll catch Azure SDK misconfiguration issues in pull requests, not in production.
One of the most confusing categories of Azure SDK for Java errors comes from mixing current-generation and previous-generation libraries in the same project. This happens more than you'd think, a developer adds azure-storage-blob (current gen), then pulls in a third-party dependency that internally uses the old azure-storage library (previous gen), and suddenly you have two competing Azure SDK ecosystems sharing a classpath.
The Azure SDK build tool will flag this with validateNoDeprecatedMicrosoftLibraryUsed, which is enabled by default. But to understand the full picture yourself, run:
mvn dependency:tree -Dincludes=com.microsoft.azure
Any artifacts under the com.microsoft.azure group ID are previous-generation libraries. Current-generation libraries use the com.azure group ID. If you see both in your dependency tree, that's your problem.
The fix depends on where the old library is coming from. If it's a direct dependency you added, swap it for the current-generation equivalent, Microsoft maintains a migration guide for each library. If it's coming in transitively through another dependency, use Maven's exclusion mechanism:
<dependency>
<groupId>com.some.vendor</groupId>
<artifactId>their-library</artifactId>
<version>1.0.0</version>
<exclusions>
<exclusion>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-storage</artifactId>
</exclusion>
</exclusions>
</dependency>
After applying exclusions, rerun mvn dependency:tree to confirm the old library is gone. Then run a full mvn compile, if the third-party library actually needs that old Azure SDK at runtime, you'll see compilation errors that tell you exactly which classes it was relying on, which gives you the information to evaluate a safe migration path.
If you generated your project with the archetype and left enableGraalVM as true (the default), your POM already includes the GraalVM native image plugin. This lets you compile your Java application into a platform-specific native binary, no JVM at runtime, faster startup, lower memory footprint. For Azure Functions or containerized microservices, this is a significant win.
Before attempting a native image build, you need GraalVM installed and JAVA_HOME pointing at it. Download GraalVM Community Edition from the GraalVM GitHub releases page and install it. Verify the native image tool is available:
native-image --version
If that command isn't found, install the native-image component:
# GraalVM 22.x and later, native-image is bundled
# For older versions:
gu install native-image
With GraalVM configured, trigger the native compilation through Maven:
mvn -Pnative package
The first run will take several minutes, native image compilation is slow. If it fails with reflection-related errors like ClassNotFoundException at image build time, you need to provide reflection configuration hints. The Azure SDK for Java ships with pre-built GraalVM metadata for its own classes, but your application code needs its own configuration. The GraalVM tracing agent can generate this automatically:
java -agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/native-image \
-jar target/my-app.jar
Run your application's typical code paths with the agent attached, it records every reflection, resource, and proxy access. The generated configuration files in META-INF/native-image will be picked up automatically on your next mvn -Pnative package run. Expect to iterate two or three times before native image compilation succeeds cleanly for a non-trivial application.
Advanced Troubleshooting
Diagnosing BOM Version Staleness in CI/CD
One thing that catches teams off guard is that the Azure SDK build tool's validateLatestBomVersionUsed check is enabled by default, meaning your CI pipeline will actually fail the build if a newer BOM version exists and you haven't updated. This is intentional behavior, not a bug. Microsoft treats an outdated BOM as a build policy violation because old versions can contain security vulnerabilities in transitive dependencies.
If this is causing unexpected CI failures, you have a few options. First, the right answer: update your BOM version. Check Maven Central for the latest azure-sdk-bom version and update your POM. Second, if your team has a controlled dependency update schedule, you can disable this specific check:
<configuration>
<validateLatestBomVersionUsed>false</validateLatestBomVersionUsed>
</configuration>
I'd strongly recommend against disabling it permanently. Instead, create a scheduled CI job that runs the build tool check weekly specifically to catch stale BOM versions, separate from your main build pipeline.
Multi-Module Maven Projects
In a multi-module Maven project, the BOM import belongs in the parent POM's <dependencyManagement> section. Child modules inherit it automatically. A common mistake is importing the BOM in a child module POM, that works, but means other child modules don't benefit from the alignment. If you see version conflicts only in certain modules, check whether they're inheriting the parent's dependency management correctly:
mvn help:effective-pom -pl my-submodule | grep azure-sdk-bom
This outputs the effective POM for a specific module, you'll see exactly what version of the BOM it's actually using at build time.
Corporate Proxy and Artifact Repository Settings
In enterprise environments, Maven Central access is often blocked. The archetype and the Azure SDK build tool need to reach Maven Central to download artifacts. If you're behind a corporate proxy or using an internal Artifactory/Nexus instance, configure your Maven settings.xml (typically at ~/.m2/settings.xml) with proxy settings and/or a mirror pointing at your internal repository that proxies Maven Central:
<settings>
<proxies>
<proxy>
<id>corp-proxy</id>
<active>true</active>
<protocol>http</protocol>
<host>proxy.yourcompany.com</host>
<port>8080</port>
</proxy>
</proxies>
</settings>
Your internal Nexus or Artifactory repository admin will need to create a proxy repository for https://repo.maven.apache.org/maven2 if one doesn't exist already. The Azure SDK archetype artifact (com.azure.tools:azure-sdk-archetype) must be available through that proxy for the mvn archetype:generate command to work.
Beta API Usage in Production Code
The Azure SDK build tool's validateNoBetaApiUsed check (enabled by default) catches calls to GA library methods that are still annotated with @Beta. These are methods in released, non-beta libraries that Microsoft hasn't fully stabilized. The check generates a build warning, not a failure by default, but you should treat these warnings seriously. Beta APIs can change signature or behavior in minor version updates without the breaking-change deprecation cycle that stable APIs go through.
If you've followed every step in this guide and are still hitting build failures or authentication errors that can't be traced to dependency configuration, it's time to escalate. Specifically, reach out to Microsoft if: (1) the Azure SDK build tool itself fails to run with an internal exception, (2) the archetype generates a project that won't compile on a clean Maven install, or (3) you're seeing runtime authentication failures that correlate to specific SDK versions. Microsoft Support has Azure SDK engineering contacts who can triage SDK-level bugs directly. File an issue on the Azure/azure-sdk-for-java GitHub repository for open-source reproducible problems, that's often faster than formal support channels.
Prevention & Best Practices
I know it can feel like overkill to think about prevention when you're just trying to get your first Azure Storage upload working. But the Azure SDK for Java ecosystem moves fast, Microsoft ships new BOM releases regularly, and libraries graduate from beta to GA on a rolling schedule. Setting up the right habits now means you're not debugging a mystery version conflict six months from now during a production incident.
The most important habit is keeping your azure-sdk-bom version current. Treat it like a security patch, it's not just about getting new features, it's about pulling in dependency updates that fix vulnerabilities in the underlying transport and serialization libraries the SDK builds on. Set a calendar reminder to check for new BOM releases monthly, or configure Dependabot or Renovate Bot on your repository to open automated pull requests when a new BOM version is published.
Wire the Azure SDK build tool into your CI/CD pipeline as a mandatory gate, not an optional check. The tool's ability to catch deprecated library usage, manual version overrides, and stale BOM references is most valuable when it runs on every pull request, before code merges into your main branch, not after a deployment breaks production.
When adding new Azure client libraries to your project, always look up the official artifact ID in the Azure SDK Releases page rather than relying on older blog posts or Stack Overflow answers. The artifact naming conventions have changed over generations of the SDK, and using an outdated artifact ID can pull in the wrong generation of the library silently.
Keep your Java version at an LTS release. The Azure SDK team targets LTS releases for primary testing and optimization. Non-LTS Java versions (like 19, 20, 21 before it became LTS) may work, but you're operating outside the primary test matrix. When LTS releases come out, Java 21, Java 25, validate your Azure SDK project against them in a branch before upgrading your production target.
- Add
mvn compile azure:runas a required step in your pull request CI pipeline to catch SDK misconfigurations before merge - Use Dependabot or Renovate Bot to automate
azure-sdk-bomversion bumps, set it to weekly cadence - Never manually specify version numbers for Azure SDK artifacts in
<dependencies>, always let the BOM resolve them - Keep a
native-imagebuild job in CI even if you don't deploy native binaries, it catches reflection and serialization issues early that only surface at compile time with GraalVM
Frequently Asked Questions
Why does my Azure SDK for Java build fail with "could not resolve artifact" even though the artifact exists on Maven Central?
This is almost always a network or repository configuration issue. In enterprise environments, direct access to Maven Central is frequently blocked by a corporate proxy or firewall. Check your ~/.m2/settings.xml to confirm proxy settings are configured, or ask your infrastructure team whether you need to use an internal Nexus or Artifactory mirror. Also verify that the artifact group ID is correct, current-generation Azure SDK artifacts use com.azure, not com.microsoft.azure. Mixing those group IDs is a very common source of resolution failures.
Can I use the Azure SDK for Java with Java 8, or do I really need to upgrade?
Java 8 is officially supported, the Azure SDK Maven archetype accepts -DjavaVersion=8 and will configure your POM accordingly. That said, Microsoft explicitly recommends JDK 17 for the best experience, and some features around async programming and newer authentication flows are smoother on 17. If your organization has a hard constraint on Java 8, the SDK will work, but you may hit edge cases that are lower priority for the SDK team to fix. Upgrading to Java 17 LTS removes a whole class of potential compatibility headaches.
What's the difference between azure-sdk-bom and the individual library versions? Why can't I just pin versions myself?
The azure-sdk-bom is a curated Bill of Materials that Microsoft tests as a cohesive set, every version combination declared in the BOM has been validated to work together without transitive dependency conflicts. When you pin versions manually, you're responsible for ensuring that every combination of transitive dependencies is compatible. The Azure SDK for Java libraries share a common HTTP pipeline, serialization layer, and authentication stack, getting those internal versions out of sync causes subtle runtime failures that are extremely hard to diagnose. The BOM eliminates this entire class of problem.
The Azure SDK build tool is failing my build because a newer BOM version exists, how do I update to the latest version?
Go to Maven Central and search for com.azure:azure-sdk-bom to find the latest version number. Update the <version> tag in your POM's <dependencyManagement> BOM import to match. Run mvn dependency:resolve to confirm everything resolves cleanly with the new version before committing. If the update pulls in a dependency that breaks something in your project, the dependency tree output will show you exactly what changed, giving you a concrete starting point for investigation.
My GraalVM native image build fails with reflection errors on Azure SDK classes, how do I fix it?
The Azure SDK for Java ships its own GraalVM reachability metadata for its core classes, so you shouldn't see reflection errors on the SDK's own types. If you are seeing them, first confirm you're on a current SDK version where that metadata is included. For your own application classes that make reflection calls (common with Jackson serialization or Spring), run the GraalVM tracing agent against your application: java -agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/native-image -jar your-app.jar. Exercise your application's full code paths during the agent run, then redo the native build with the generated configuration files in place.
Should I disable the sendToMicrosoft telemetry setting in the Azure SDK build tool?
It depends entirely on your organization's data governance policies. The telemetry collects build report data, which Azure libraries you're using, which BOM version, whether you're hitting deprecated APIs, to help Microsoft prioritize documentation and SDK improvements. No personally identifiable information or source code is transmitted. In a regulated industry (healthcare, finance, government) or in an air-gapped environment, disabling it with <sendToMicrosoft>false</sendToMicrosoft> is the safe default. For everyone else, leaving it enabled helps make the SDK better for the whole community.