rguides

message

Overview

message() sends diagnostic output to the stderr() connection. Unlike stop(), it does not halt the function that calls it. Unlike warning(), it does not mark the output as exceptional. It is purely informational output that a user or developer sees as the program runs.

You will encounter message() in three situations: when writing your own functions, when suppressing messages from others’ code, and when R itself reports package loading progress. message() is the lowest-key output mechanism R provides — it exists to tell you something without implying anything is wrong.

Signature

message(…, domain = NULL, appendLF = TRUE)
suppressMessages(expr)
packageStartupMessage(…, domain = NULL, appendLF = TRUE)

Parameters

ParameterDescription
One or more objects. R coerces each to character and pastes them together with no separator. A single condition object is also accepted as the only argument.
domainPassed to gettext() for localization. Set NA to skip translation lookup.
appendLFLogical. When TRUE (the default), R appends a newline after the message text. Set FALSE to keep output on the same line as subsequent output.
exprAn expression. suppressMessages() evaluates it in a context where all message() calls are silenced.

Return value

message() returns NULL invisibly. It is called purely for its side effect.

Basic usage

message("Data import complete")
# Stderr: Data import complete

When you pass multiple arguments to message(), R converts each to character and pastes them together with no separator between them. This is different from paste() which requires an explicit call — message() handles the coercion and concatenation internally, so you can freely mix strings, numbers, and variable references without building the string yourself first. New users often miss this convenience and construct strings with paste() before passing a single argument to message() when the direct approach works fine.

message("User ", username, " logged in at ", Sys.time())
# Stderr: User alice logged in at 2026-01-15 10:30:00

Setting appendLF = FALSE suppresses the automatic newline that message() normally appends, which is useful when you want to build up a line of output across multiple calls. A common pattern is printing progress dots or updating a percentage counter in place — you issue several message() calls with appendLF = FALSE and finish with a "\n" to close the line. This approach works in both interactive sessions and non-interactive scripts because message() always flushes to stderr immediately regardless of whether the output is line-buffered.

message("Loading: 75%", appendLF = FALSE)
cat(" [done]\n")
# Stderr: Loading: 75% [done]

Suppressing messages

When you need to silence diagnostic output from code you do not control — for instance, from third-party packages that emit verbose progress messages during startup — wrapping the expression in suppressMessages() blocks all message() calls within that evaluation context. This is the intended filtering mechanism in R, and package authors rely on it; they use message() precisely because users can suppress it without affecting the function’s return value or its other side effects.

suppressMessages(message("This will not appear"))
# No output

This only suppresses message() calls. Warnings and errors pass through unchanged. To suppress those too, use suppressWarnings() or tryCatch() respectively.

Condition objects

message() accepts a condition object as its sole argument. When you do this, additional arguments are silently ignored and a warning is raised:

my_cond <- simpleMessage("condition message")
message(my_cond)
# This works but ignores any other arguments passed alongside

For custom condition handling, tryCatch() or withCallingHandlers() give you more control. The muffleMessage restart is active while a message is being processed, letting you intercept it programmatically.

Messages vs warnings vs errors

| Function | Execution continues | Output destination | Use case | |----------|--------------------|--------------------| | message() | Yes | stderr | Progress, debug, informational | | warning() | Yes | stderr | Something unexpected but recoverable | | stop() | No | stderr | Fatal error, code must stop |

The practical difference between message() and warning() is that warnings can be promoted to errors via options(warn = 2), and the R documentation explicitly represents messages and warnings as distinct condition types. A messageCondition is not the same as a warningCondition.

Package startup messages

packageStartupMessage() is designed for package loading output. It behaves like message() but is specifically intended for boot-time diagnostics. Package authors call this inside .onLoad() and .onAttach() hooks so that the messages appear when a user loads the package with library() or require(). The key benefit over plain message() is that users can suppress startup messages specifically without silencing diagnostic output from elsewhere in the package, using the dedicated suppressPackageStartupMessages() function, which leaves normal message() calls untouched.

# In a package's .onLoad function:
packageStartupMessage("Loading myPackage v1.0")

The separation between startup messages and regular diagnostic output means you can silence noisy package-loading banners while still seeing progress messages from long-running computations within the same package. This distinction is especially valuable in RMarkdown and Quarto documents where you want clean output but need to keep computational diagnostics visible for reproducibility.

suppressPackageStartupMessages(library(myPackage))

Common mistakes

Confusing message() with stop(). message() does not halt execution — it emits text to stderr and the calling function continues to the next statement. This is a frequent source of bugs when developers coming from languages where printing an error terminates the program expect message() to act as a fatal signal. If you want execution to stop, use stop(), which raises an error condition that propagates up the call stack unless caught by a handler. R distinguishes clearly between informational output and error conditions, and mixing them up leads to silent failures that are hard to debug.

# Wrong: thinking message() stops the code
message("File not found")
# Code continues past this point

# Right: stop() halts execution
stop("File not found")

Writing to the wrong stream. message() sends to stderr(), not stdout(). This matters when redirecting output — for instance, when you capture the output of an R script with shell redirection or system2(), the messages land in the error stream rather than standard output. If you write a script that produces data on stdout and progress on stderr, the separation is deliberate and useful. But if you expect message() output to appear in a log file captured via stdout=, it will not — you need to capture stderr separately or use cat() for stdout-bound diagnostics instead.

# stdout redirect misses message() output
system2("Rscript", args = c("-e", "message('hi')"), stdout = "out.txt", stderr = "err.txt")
# 'hi' appears in err.txt, not out.txt

Assuming suppressMessages() hides warnings. It does not — suppressMessages() only intercepts conditions of class message, which are entirely distinct from warnings (class warning) and errors (class error). The condition system in R is hierarchical, and each suppression function targets exactly one branch: suppressMessages() for messages, suppressWarnings() for warnings, and tryCatch() or try() for errors. If you need to silence everything simultaneously, you must nest the calls or use withCallingHandlers() to install a custom handler that muzzles all three condition types in one go.

suppressMessages(warning("This warning still appears"))
# [1] This warning still appears

message() writes to stderr, not stdout. This means it appears in the console during interactive use but does not get captured by capture.output(). Use message() for diagnostic output in packages so users can suppress it with suppressMessages() without affecting return values.

See also

/reference/base-functions/stop/ /reference/base-functions/warning/ /reference/base-functions/cat/