Procfile validator

Paste a Procfile to see which lines are valid process entries, which are not, and why. You get a table of process types, a list of issues with line numbers and fixes, a check of each line against what Rig does and what Heroku, Foreman, and Honcho document, and a cleaned-up copy of the file. The check runs in your browser, so nothing you paste is sent anywhere.

Updated

Worked example

Example input
# Processes for local development
web: bundle exec puma -p 3000
worker:	bundle exec sidekiq
  assets: yarn build --watch
release: bundle exec rails db:migrate
web: bundle exec puma -p $PORT
clock bundle exec clockwork clock.rb
mailer.preview: bundle exec mailcatcher --foreground
cache:
logs: tail -f log/development.log | grep -v health
Output
Procfile check
5 process types on 6 lines, 3 invalid lines. 3 errors, 2 warnings, 5 notes. 10 lines read.

Process types
  Line  Process type  Command                                       Notes
  2     web           bundle exec puma -p 3000                      no $PORT
  3     worker        bundle exec sidekiq                           tab after colon
  4     assets        yarn build --watch                            indented
  5     release       bundle exec rails db:migrate                  release phase
  6     web           bundle exec puma -p $PORT                     repeats line 2
  10    logs          tail -f log/development.log | grep -v health  shell syntax

Lines Rig skips
  Line 7 (no-colon): clock bundle exec clockwork clock.rb
  Line 8 (invalid-name-characters): mailer.preview: bundle exec mailcatcher --foreground
  Line 9 (empty-command): cache:

Issues (10)
  - info, line 1 (comments-undocumented): The file has 1 comment line. Comment lines are not part of the format that Heroku documents. Rig skips lines that start with #.
    Fix: Keep the comments if you only use Rig. If you deploy to Heroku, test that they are accepted, or keep the notes in a README.
  - info, line 2 (web-no-port): The web command does not reference $PORT. Heroku sets PORT and expects the web process to bind to it. If the program reads PORT itself, nothing needs to change. The command looks like it passes a fixed port (3000). Rig also exports PORT when a port is set for the project.
    Fix: Pass the port from the environment where your server takes a port argument, for example --port $PORT, or read the PORT variable in code.
  - info, line 3 (tab-after-colon): A tab follows the colon. Rig accepts any whitespace there, but the documented form uses a space.
    Fix: Use one space after the colon. The normalised output does.
  - warning, line 4 (leading-whitespace): The line is indented. Rig trims leading whitespace, but the Heroku documentation shows lines that start in the first column, and other runners may skip an indented line.
    Fix: Remove the indentation.
  - info, line 5 (release-process): On Heroku the release process type runs in the release phase, before a new release is deployed, and a failure stops that release. It is not a long-running process, and heroku local does not run it. Rig lists it as an ordinary script you can start.
    Fix: Use release for one-off tasks such as database migrations, and run those yourself when you work locally.
  - warning, line 6 (duplicate-process): The process type "web" is defined again here (first on line 2). Behaviour differs between runners. Rig keeps the first definition and ignores this one. Other runners may use the last one instead.
    Fix: Delete one definition, or rename one process type, so the file does not depend on which rule a runner follows.
  - error, line 7 (no-colon): The line has no colon, so it is not a process line. Rig skips it without a warning. Each line must look like name: command.
    Fix: Put the process type and a colon at the start of the line. If "clock" is the process type, write "clock: bundle exec clockwork clock.rb".
  - error, line 8 (invalid-name-characters): The process type contains characters that are not allowed: "." (U+002E). Heroku documents letters, digits, hyphens, and underscores, and Rig skips the line.
    Fix: Use only letters, digits, hyphens, and underscores in the process type, for example mailer-preview.
  - error, line 9 (empty-command): The process type "cache" has no command after the colon. Rig skips the line, and the documented form needs a command.
    Fix: Add the command after the colon, or delete the line.
  - info, line 10 (shell-features): The command uses shell syntax (|), which only a shell interprets. Rig runs the line through /bin/sh -c, and through cmd.exe on Windows. When a port is set, Rig adds " --port N" to the end of the whole line, so the flag goes to the last command in a chain or pipe.
    Fix: Keep it if it works for you. To avoid depending on a shell, put the steps in a script and call the script.

Compatibility by line
  Line  Type       Rig  Heroku          Foreman         Honcho
  2     web        yes  yes             yes             yes
  3     worker     yes  not documented  not documented  not documented
  4     assets     yes  not documented  not documented  not documented
  5     release    yes  yes             yes             yes
  6     web        no   not documented  not documented  not documented
  7     (invalid)  no   no              no              no
  8     (invalid)  no   no              no              no
  9     (invalid)  no   no              no              no
  10    logs       yes  yes             yes             yes

  Line 3 (Heroku, Foreman, Honcho): Not described in the documentation: a tab or other whitespace after the colon.
  Line 4 (Heroku, Foreman, Honcho): Not described in the documentation: an indented line.
  Line 6 (Rig): Rig keeps the first "web" (line 2) and ignores this one.
  Line 6 (Heroku, Foreman, Honcho): Not described in the documentation: a repeated process type.
  Line 7 (Heroku, Foreman, Honcho): There is no colon, so the line is not in the form name: command.
  Line 8 (Heroku, Foreman, Honcho): The process type uses characters outside letters, digits, hyphens, and underscores.
  Line 9 (Heroku, Foreman, Honcho): There is no command after the colon.

  Rig is judged from its parser code, and it skips an invalid line without reporting an error.
  Heroku, Foreman, and Honcho are judged only from their published documentation. "not documented"
  means that documentation does not describe that form of line, not that the runner rejects it.
  Comments, indentation, repeated process types, and line endings are not documented by Heroku, so
  test a deploy if they matter to you.

Normalised Procfile
  # Processes for local development
  web: bundle exec puma -p 3000
  worker: bundle exec sidekiq
  assets: yarn build --watch
  release: bundle exec rails db:migrate
  web: bundle exec puma -p $PORT
  logs: tail -f log/development.log | grep -v health

Read the report from the top. Six lines are process entries and three are not: line 7 has no colon, line 8 has a dot in the process type, and line 9 has no command. Rig skips all three without a message, so clock, mailer.preview, and cache would never appear as scripts.

Line 6 repeats web. Rig keeps the first definition on line 2 and ignores line 6, but the Heroku documentation does not say which one wins, so this is a warning and not a guess. Line 2 passes the fixed port 3000 with -p, which is why it carries a note about $PORT. Line 6 uses $PORT.

Lines 3 and 4 work in Rig but are not described in the Heroku, Foreman, or Honcho documentation: a tab after the colon, and indentation. The compatibility table shows them as not documented, which is different from rejected. Line 5 is a release entry, which Heroku runs once before a deploy, and line 10 has a pipe, so it needs a shell.

The normalised copy drops the three invalid lines, removes the indentation, and uses one space after each colon. It keeps both web lines, because choosing between them is your decision.

How to use it

  1. Paste the file

    Paste the contents of the file named Procfile from your project root. The validator reads text only, up to 50 KB and 1000 lines. Binary content is refused, never guessed at.

  2. Fix the errors first

    An error is a line that Rig skips and the documented format rejects: no colon, nothing after the colon, or a character in the process type other than letters, digits, hyphens, and underscores. Each one has a line number and a fix.

  3. Read the warnings

    A warning marks something that works in Rig but may not work elsewhere: an indented line, a repeated process type, a byte order mark, or a very long command. Decide whether the file has to run anywhere besides Rig. This page cannot report Windows line endings, because a text box turns them into LF, so look at line endings in your editor.

  4. Check the compatibility table

    Each line shows whether Rig loads it and whether Heroku, Foreman, and Honcho document that form. Not documented means their documentation says nothing about it. It does not mean they reject the line.

  5. Look at the notes

    Notes cover the web and release process types, a web command that does not mention $PORT, and commands that rely on a shell. They are information, not faults.

  6. Copy the normalised file

    The normalised copy uses LF line endings, no indentation, and one space after each colon. It leaves out invalid lines and never repairs them, so compare it with your original before you replace the file.

How it works

The validator applies these rules in order. Rules about Rig come from reading Rig’s own parser. Rules about other runners are limited to what their documentation says.

  1. Limits. The input must be a string of at most 50 KB (51,200 bytes of UTF-8) and 1000 lines, with no NUL characters. Anything else is refused with a fixed message, and nothing is cut short.
  2. Line endings. A leading byte order mark is noted and removed. Lines end at LF, and a CR directly before an LF belongs to a CRLF ending. A CR anywhere else stays in the line. Rig splits lines the same way.
  3. Blank lines and comments. Each line is trimmed. A line with nothing left is blank, and a line that starts with # after trimming is a comment. Rig skips both, and it has no continuation lines.
  4. Entries. Any other line is an entry when it matches Rig’s pattern, ^([A-Za-z0-9_-]+):\s*(.+)$: a process type of letters, digits, hyphens, and underscores, a colon, optional whitespace, and a command. Because Rig trims the line first, indentation, trailing whitespace, and a tab after the colon are all accepted.
  5. Invalid lines. Every other line gets one reason: no colon, nothing before the colon, nothing after it, whitespace before the colon, a character outside letters, digits, hyphens, and underscores in the process type, or a line break character inside the line. Rig skips these lines without reporting anything.
  6. Repeated process types. Every repeat is listed and reported as a warning, because behaviour differs between runners. Rig keeps the first definition and ignores the rest. The Heroku documentation does not say which one wins, so the validator does not guess.
  7. The web and release types. Heroku documents web as the only process type that receives HTTP traffic from its routers, and says that process must bind to the port in the PORT environment variable. It documents release as the command that runs in the release phase, before a new release is deployed. The validator notes a web command that does not mention $PORT, ${PORT}, or %PORT%, and it notes any release entry.
  8. Shell syntax. A quick scan outside quotes finds &&, ||, pipes, semicolons, redirects, a background &, $( ), backticks, and inline # comments. Rig runs each command with /bin/sh -c, or with cmd.exe on Windows. When a port is set, it adds --port N to the end of the whole line and exports PORT.
  9. Long commands. A command over 500 characters is flagged. That limit belongs to this tool and is not a runner’s rule.
  10. Normalising. The output keeps comments and entries in order, writes name: command, uses LF, and ends with one newline. It drops invalid lines and collapses runs of blank lines.

The compatibility table says yes when a line matches the form a runner documents, no when it does not, and not documented when the documentation is silent. Heroku documents the form of a process type, a colon, and a command, process types that are alphanumeric with hyphens and underscores, and a file named exactly Procfile in the root directory. The Foreman man page lists letters, numbers, and the underscore for process names, so a hyphen shows as not documented there. Honcho documents letters, digits, underscores, and dashes, and calls the command a shell command line.

Limitations

  • It checks syntax and documented rules only. It cannot tell whether a command exists, whether a port is free, or whether a process will start.
  • Heroku, Foreman, and Honcho are judged only from their published documentation, which, as checked for this tool, says nothing about comments, indentation, tabs, repeated process types, or line endings. Those show as not documented, not as failures.
  • Overmind and other runners are not in the compatibility table. The validator only compares against documentation it has checked.
  • The shell check is a quick scan for common syntax such as &&, pipes, and redirects. It is not a shell parser, so unusual quoting can be misread.
  • Each file can be up to 50 KB and 1000 lines. A larger file is refused, not cut short, so a result never covers only part of a file.

Practical applications

Use it whenever a Procfile does not behave the way you expect.

  • Moving to Heroku. Check the process type names, the web command, and any release line before you deploy.
  • Running a Heroku-style app locally. Foreman, Honcho, and Rig read the same kind of file. Compare how each one treats yours.
  • A process that never shows up. A line that was skipped is the usual reason, such as one with a space before the colon or a dot in the name.
  • Code review. Paste the Procfile from a pull request and read the issues list instead of checking each line by eye.
  • Cleaning up. Normalise line endings, indentation, and spacing after merging files from several people or editors.

Common mistakes

  • Naming the file Procfile.txt, Procfile.dev, or procfile. Heroku requires the exact name Procfile. Rig looks for a file named Procfile in the project root, and does not look for names such as Procfile.dev.
  • Writing a process type with a dot or a space, such as mailer.preview or my worker. Use letters, digits, hyphens, and underscores.
  • Leaving a space before the colon, as in web : node server.js. The colon has to follow the process type directly.
  • Hard-coding a port in the web command. Heroku assigns PORT and expects the web process to bind to it, so read PORT or pass $PORT.
  • Defining the same process type twice and assuming the last one wins. Rig keeps the first, and other runners may differ, so keep one definition.

Frequently asked questions

What is a Procfile?

A Procfile is a plain text file named Procfile that lists the processes of an app, one per line, as a process type, a colon, and a command. Heroku uses it to decide what each dyno runs. Runners such as Foreman, Honcho, and Rig read the same format to start the processes on your machine.

What is the exact format of a Procfile line?

The line is a process type, a colon, a space, and then the command, for example web: node server.js. Heroku describes the process type as alphanumeric and also allows hyphens and underscores. The command is the line you would type in a shell to start that process.

Does a Procfile need a web process?

Only if the app serves HTTP traffic on Heroku. The web process type is the only one that receives HTTP traffic from Heroku’s routers, and its command must bind to the port in the PORT environment variable. An app with only background workers does not need a web line.

What does the release process type do?

On Heroku, the release command runs in the release phase, before a new release is deployed. If it fails, the new release is not deployed. It suits tasks such as database migrations. The heroku local command does not run it, so run it yourself when you work locally.

Are comments allowed in a Procfile?

Rig skips lines that start with #. The Heroku documentation does not describe comments, so the validator lists them as a note and does not claim that Heroku rejects them. If you deploy to Heroku and want certainty, test a deploy or keep your notes in a README.

What happens when two lines use the same process type?

It depends on the runner. Rig keeps the first definition and ignores later ones. The Heroku documentation does not say which one wins, and the validator does not guess for other runners, so it reports a warning that behaviour differs between runners. Delete one of the lines so the file does not depend on a rule.

Sources

  1. Heroku Dev Center: The ProcfileOfficial documentation, checked 13 October 2026
  2. Heroku Dev Center: Preparing a Codebase for Heroku DeploymentOfficial documentation, checked 13 October 2026
  3. Heroku Dev Center: Runtime PrinciplesOfficial documentation, checked 13 October 2026
  4. Heroku Dev Center: Dyno Startup BehaviorOfficial documentation, checked 13 October 2026
  5. Heroku Dev Center: Release PhaseOfficial documentation, checked 13 October 2026
  6. Heroku Changelog: Heroku local no longer runs the release process typeOfficial documentation, checked 13 October 2026
  7. Heroku Dev Center: Running Apps LocallyOfficial documentation, checked 13 October 2026
  8. foreman(1): manage Procfile-based applicationsOfficial documentation, checked 13 October 2026
  9. Honcho documentation: Using ProcfilesOfficial documentation, checked 13 October 2026
  10. Rig documentation: Procfile projects (parser behaviour confirmed in Rig’s source code)Rig source code, checked 13 October 2026

Procfile projects in Rig

Rig reads a file named Procfile in your project root and turns each process type into a script you can select and start. It skips blank lines and lines that start with #, runs each command through /bin/sh -c (cmd.exe on Windows), and exports PORT when you set a port for the project. You do not need Rig to use this validator.

Related

https://userig.app/tools/procfile-validator