# Drone Build Error: Complete Troubleshooting Guide

Drone CI is a container-native CI/CD platform that runs pipelines in Docker containers. When builds fail, it's usually related to Docker execution, pipeline configuration, or secret management.

Let me walk through the most common Drone build errors and how to fix each one systematically.

Understanding Drone Pipeline Logs

Drone logs are straightforward but can be sparse:

  1. 1.Go to your repository in Drone
  2. 2.Click on the failed build number
  3. 3.Click on the failed step to expand logs
  4. 4.Look for exit code 1 or error messages

Drone uses a simple YAML format that's different from other CI systems. Understanding the structure helps debug issues.

Fix 1: Pipeline YAML Syntax Errors

Drone YAML has specific requirements.

Symptoms: - Build doesn't start - "YAML parsing error" - Pipeline ignored completely

Common YAML issues:

```yaml # WRONG - missing kind/type at top pipeline: build: image: node:20 commands: - npm install

# CORRECT - specify pipeline type kind: pipeline type: docker name: default

steps: - name: build image: node:20 commands: - npm install ```

Other syntax problems:

```yaml # WRONG - old format (Drone 0.8) pipeline: build: image: node:20

# CORRECT - new format (Drone 1.0+) kind: pipeline type: docker name: default

steps: - name: build image: node:20 ```

Solution:

Validate YAML syntax:

```yaml kind: pipeline type: docker name: default

steps: - name: install image: node:20 commands: - npm ci

  • name: test
  • image: node:20
  • commands:
  • - npm test
  • name: build
  • image: node:20
  • commands:
  • - npm run build
  • `

Fix 2: Docker Image Pull Failures

Images can't be pulled or don't exist.

Symptoms: - "Error: image pull failed" - "Error: manifest unknown" - Long delay before build starts

Solution A: Use public images correctly:

yaml
steps:
- name: build
  image: node:20.11.0-alpine  # Specify exact tag
  commands:
  - npm ci

Solution B: Use private images:

yaml
steps:
- name: build
  image: registry.company.com/my-image:latest
  pull: always  # Always pull latest
  commands:
  - ./build.sh

For private registries, configure pull secrets:

```yaml kind: secret name: docker_password get: path: secrets/docker name: password

kind: pipeline type: docker name: default

steps: - name: build image: registry.company.com/my-image:latest pull_secrets: - docker_config ```

Or in Drone server config:

bash
# Configure Docker registry in Drone server
DRONE_DOCKER_CONFIG=/path/to/docker/config.json

Solution C: Use local images:

yaml
steps:
- name: build
  image: my-local-image
  pull: if-not-exists  # Only pull if not present locally

Fix 3: Container Execution Errors

Commands fail inside containers.

Symptoms: - command not found - Permission denied - Exit code 127

Solution A: Choose correct base image:

```yaml # For Node.js - name: build image: node:20 commands: - npm --version # npm is available

# For Python - name: test image: python:3.11 commands: - pip install pytest - pytest

# For Go - name: build image: golang:1.21 commands: - go build ```

Solution B: Install missing tools:

yaml
- name: build
  image: node:20
  commands:
  - apt-get update && apt-get install -y jq curl
  - npm ci

Solution C: Fix permissions:

yaml
- name: build
  image: node:20
  commands:
  - chmod +x ./scripts/*.sh
  - ./scripts/build.sh

Important: Drone runs commands in /drone/src as a non-root user by default.

Fix 4: Environment Variable Issues

Variables not available or incorrectly formatted.

Symptoms: - Empty values in variables - Wrong syntax used

Solution A: Use correct variable syntax:

yaml
steps:
- name: build
  image: node:20
  environment:
    NODE_ENV: production
    API_KEY:
      from_secret: api_key  # Reference secret
  commands:
  - echo $NODE_ENV
  - npm run build

Solution B: Pipeline-level environment:

```yaml kind: pipeline type: docker name: default

environment: NODE_ENV: test APP_VERSION: 1.0.0

steps: - name: build image: node:20 commands: - echo $NODE_ENV - echo $APP_VERSION ```

Solution C: Matrix builds with variables:

```yaml kind: pipeline type: docker name: default

matrix: NODE_VERSION: - 18 - 20 - 22

steps: - name: test image: node:${NODE_VERSION} commands: - node --version - npm test ```

Fix 5: Secret Management Errors

Secrets not accessible or incorrectly configured.

Symptoms: - from_secret: ... returns empty - Secrets don't get injected

Solution A: Define secrets in Drone:

Using Drone UI:

  1. 1.Go to your repository in Drone
  2. 2.Click "Settings" → "Secrets"
  3. 3.Add secrets (they're encrypted at rest)

Using CLI:

bash
drone secret add --repository myorg/myrepo --name api_key --value my_secret_value

Solution B: Use secrets in pipeline:

yaml
steps:
- name: deploy
  image: plugins/docker
  settings:
    repo: myorg/myrepo
    username:
      from_secret: docker_username
    password:
      from_secret: docker_password

Solution C: External secret stores:

Drone can use external secret backends:

```yaml # Using Kubernetes secrets kind: secret name: kube_token get: path: kube-secrets name: token

# Using HashiCorp Vault kind: secret name: vault_secret get: path: vault/data/myapp name: password ```

Configure in Drone server:

bash
DRONE_SECRET_PLUGIN_ENDPOINT=http://vault-plugin:3000

Fix 6: Volume and Workspace Issues

Files not persisting between steps.

Symptoms: - Artifacts from one step not visible in next - Cache not working

Solution A: Use workspace correctly:

Drone automatically shares /drone/src between steps:

```yaml steps: - name: build image: node:20 commands: - npm ci - npm run build # Output goes to /drone/src/dist

  • name: deploy
  • image: alpine
  • commands:
  • - ls -la /drone/src/dist # Available from previous step
  • `

Solution B: Use volumes for caching:

```yaml kind: pipeline type: docker name: default

volumes: - name: npm_cache temp: {}

steps: - name: install image: node:20 volumes: - name: npm_cache path: /root/.npm commands: - npm ci --cache /root/.npm

  • name: test
  • image: node:20
  • volumes:
  • - name: npm_cache
  • path: /root/.npm
  • commands:
  • - npm test
  • `

Solution C: Host volumes:

```yaml volumes: - name: global_cache host: path: /var/lib/drone/cache

steps: - name: build image: node:20 volumes: - name: global_cache path: /cache ```

Fix 7: Plugin Configuration Errors

Drone plugins have specific configuration requirements.

Symptoms: - Plugin fails silently - Settings not applied

Solution A: Use plugin settings correctly:

```yaml # Docker plugin - name: publish image: plugins/docker settings: repo: myorg/myrepo tags: latest dockerfile: Dockerfile username: from_secret: docker_username password: from_secret: docker_password

# SSH plugin - name: deploy image: appleboy/drone-ssh settings: host: deploy.company.com username: deploy password: from_secret: ssh_password script: - ./deploy.sh

# Slack notification - name: notify image: plugins/slack settings: webhook: from_secret: slack_webhook channel: builds template: "Build {{build.number}} completed" ```

Solution B: Check plugin documentation:

Each plugin has its own settings format. Check:

  • plugins/docker: Docker Hub/registry publishing
  • plugins/github-release: GitHub releases
  • appleboy/drone-ssh: SSH deployments
  • appleboy/drone-git-push: Git push

Fix 8: Trigger Conditions

Pipelines not triggering correctly.

Symptoms: - Build doesn't start on push - Wrong branches trigger builds - PRs not triggering

Solution A: Configure triggers:

```yaml kind: pipeline type: docker name: default

trigger: branch: - main - develop event: - push - pull_request ```

Solution B: Exclude events:

```yaml trigger: event: exclude: - tag # Don't run for tags

branch: exclude: - gh-pages ```

Solution C: Use conditions:

yaml
steps:
- name: deploy
  image: alpine
  when:
    branch:
    - main
    event:
    - push
  commands:
  - ./deploy.sh

Fix 9: Resource Limits

Builds fail due to resource constraints.

Symptoms: - Out of memory - Timeout exceeded - Container killed

Solution A: Increase resources:

Drone containers inherit from Docker:

yaml
steps:
- name: build
  image: node:20
  commands:
  - npm run build

For self-hosted Drone, increase Docker daemon limits.

Solution B: Split into multiple pipelines:

```yaml kind: pipeline type: docker name: build

steps: - name: build image: node:20 commands: - npm run build

---

kind: pipeline type: docker name: test

steps: - name: test image: node:20 commands: - npm test

depends_on: - build ```

Solution C: Use timeout:

yaml
steps:
- name: long-test
  image: node:20
  commands:
  - npm run test:e2e
  failure: ignore  # Don't fail pipeline if this step fails

Fix 10: Clone Step Failures

Repository clone fails.

Symptoms: - "fatal: could not read Username" - "repository not found" - Clone timeout

Solution A: Disable default clone:

```yaml kind: pipeline type: docker name: default

clone: disable: true

steps: - name: custom-clone image: alpine/git commands: - git clone https://github.com/myorg/myrepo.git . ```

Solution B: Configure clone depth:

```yaml clone: depth: 50 # Shallow clone

steps: - name: build image: node:20 commands: - npm run build ```

Solution C: Private repositories:

Drone server handles authentication for private repos:

bash
# Configure in Drone server
DRONE_GITHUB_CLIENT_ID=...
DRONE_GITHUB_CLIENT_SECRET=...

Quick Reference: Drone Errors

ErrorCauseSolution
YAML parsing errorOld format or syntaxUse new format, validate YAML
Image pull failedRegistry/auth issueUse correct image, configure auth
command not foundWrong base imageUse image with required tools
Secret emptyNot definedAdd secret in Drone UI
Volume not workingMissing configDefine volumes, use correct path
Build not triggeringWrong trigger configSet trigger conditions
Clone failedAuth issueConfigure OAuth, check repo access

Debugging Commands

Add to your pipeline:

yaml
steps:
- name: debug
  image: alpine
  commands:
  - echo "=== Environment ==="
  - env | sort
  - echo "=== Workspace ==="
  - pwd
  - ls -la /drone/src
  - echo "=== Drone Info ==="
  - echo "Branch: $DRONE_BRANCH"
  - echo "Commit: $DRONE_COMMIT"
  - echo "Build: $DRONE_BUILD_NUMBER"