JFrog Artifactory Certified DevOps Engineer common mistakes
JFrog Artifactory Certified DevOps Engineer · Understand the traps and how to avoid them.
When defining a virtual repository, they set a remote repository as its default deployment repository, or they expect an upload to a virtual repository to be written into every local repository it aggregates.
Virtual repositories are read-through aggregations; deployment must resolve to exactly one local repository, and the UI allows selecting only repositories that are included in the virtual repository.
What to do instead
Include a specific local repository in the virtual repository and set that local repository as the virtual repository's default deployment repository. Verify by deploying a test artifact and checking which local repository received it; remember that resolution order and deployment target are separate settings.
They configure remote repository include/exclude patterns with shell globs such as *.jar or org/example/*, then see 404s for valid Maven or npm paths or cache paths they did not intend to cache.
Artifactory uses Ant-style patterns relative to the repository root, with ** matching across path separators; a single * does not cross directory boundaries, and patterns are easy to test incorrectly in a browser rather than through Artifactory.
What to do instead
Use patterns such as /*.jar or org/example/ and test them with the remote repository's test/preview control before saving. Remember that include patterns restrict what Artifactory will fetch and cache; exclude patterns remove matching paths even if an include pattern would allow them.
They assume push replication is bidirectional or that deleting an artifact on the source repository automatically removes it from the replication target.
Replication is configured per repository and per direction; push copies from source to target and pull copies from target to source. Deletion propagation is not the default behaviour and must be enabled explicitly in the replication configuration.
What to do instead
Model replication as one-way: create a push replication on the source and, if needed, a separate pull replication on the other side. If deletions must propagate, enable the deletion option in the push replication configuration and test with a disposable artifact; otherwise use Distribution or a controlled cleanup job on the target.
They upload artifacts with jfrog rt upload --build-name and --build-number but never publish build-info, then expect the Builds tab to show the build or expect dependencies to be captured automatically.
The upload command only tags artifacts with build metadata; publishing build-info is a separate step, and dependency/environment capture requires a package-specific build-info extractor or explicit collection.
What to do instead
After upload, run jfrog rt build-publish with the same build name and number. For Maven, Gradle, npm, NuGet, and similar tools, use the JFrog build-info extractor or native integration so dependencies, environment variables, and issues are captured, then publish the build-info to the configured build-info repository.
They use /api/search/artifact?name=... for complex metadata queries, send AQL as a GET request, or forget to URL-encode repository paths and artifact names.
The simple search endpoints cover only limited name/path lookups; AQL requires a POST body to /api/search/aql with an appropriate content type. Repository paths often contain characters that must be encoded, and authentication headers are easy to omit.
What to do instead
Use POST /api/search/aql with a text/plain body for property, build, and cross-repository queries. URL-encode paths when calling /api/storage/{repo}/{path}, /api/copy, /api/move, and /api/delete, and authenticate with an access token in the Authorization: Bearer header or with X-JFrog-Art-Api.
They enable anonymous access or grant the Any user read access across repositories to make a failing build work, instead of creating a permission target for a group.
Repository creation and authorization are separate: a new repository is not automatically restricted, and anonymous access is a global setting. Candidates often confuse repository-level roles with global user roles and take the fastest path to a green build.
What to do instead
Create a group, create a permission target that includes the required repositories and builds, and assign only the needed roles (read, annotate, deploy, delete, manage) to that group. Disable anonymous access where policy requires it, and verify with the effective-permissions view or a test account before handing the build to CI.
They hand-edit configuration files for settings that belong in system.yaml, or they change a port or TLS setting and restart only Artifactory while leaving Router untouched.
Artifactory 7.x separates platform configuration (system.yaml) from the binary provider configuration (binarystore.xml) and runs Router and Artifactory as distinct services. Old habits from earlier versions and single-service restarts produce configurations that appear saved but are not applied end to end.
What to do instead
Put platform and Artifactory settings in $JFROG_HOME/artifactory/var/etc/system.yaml, keep binarystore.xml for the filestore provider, and restart both Router and Artifactory after port, TLS, or routing changes. Verify the Router port (commonly 8082) and the Artifactory port (commonly 8081) independently with curl.
They create a Docker repository as a generic repository, or create an npm repository for Maven artifacts, then wonder why docker push fails or why Maven metadata and remote path handling are wrong.
Artifactory's package type determines path handling, metadata generation, remote repository behaviour, and client support. Docker in particular requires a Docker-type repository and correct reverse-proxy or subdomain configuration.
What to do instead
Choose the correct package type at repository creation: docker for Docker local/remote/virtual repositories, maven for Maven, npm for npm, and generic only for arbitrary files. Configure the Docker reverse proxy or subdomain before pushing, and remember that the package type is not a casual post-creation toggle.
They delete an artifact or a Docker image tag and expect disk usage to drop immediately, then conclude that deletion is broken when storage remains unchanged.
Artifactory stores blobs by checksum and moves deleted items to the trash can; Docker tag deletion does not necessarily remove the manifest or layers. Garbage collection is a separate process that reclaims unreferenced blobs.
What to do instead
Empty the trash can and run garbage collection, then recheck storage. For Docker, delete the tag and, where appropriate, the manifest through the Docker API, then run garbage collection; schedule GC during a maintenance window and confirm that no other repositories reference the same checksums.
They treat a Release Bundle as an ordinary repository and try to deploy artifacts directly into it, or they create a bundle without signing it and are surprised when distribution to an edge node fails.
Release Bundles are immutable Distribution objects created from build-info or artifact queries, versioned, and signed; they are not writable repositories. Distribution also depends on the Distribution service and edge nodes, not just the Artifactory repository configuration.
What to do instead
Create the release bundle from build-info or AQL using the Distribution REST API or jfrog ds, sign it with the configured GPG key, and distribute it to the intended edge nodes. Treat the bundle as immutable; to change content, create a new version rather than deploying into the bundle.