8.5.x bootstrap.inc drupal_set_message($message = NULL, $type = 'status', $repeat = FALSE)
8.0.x bootstrap.inc drupal_set_message($message = NULL, $type = 'status', $repeat = FALSE)
8.1.x bootstrap.inc drupal_set_message($message = NULL, $type = 'status', $repeat = FALSE)
8.2.x bootstrap.inc drupal_set_message($message = NULL, $type = 'status', $repeat = FALSE)
8.3.x bootstrap.inc drupal_set_message($message = NULL, $type = 'status', $repeat = FALSE)
8.4.x bootstrap.inc drupal_set_message($message = NULL, $type = 'status', $repeat = FALSE)
8.6.x bootstrap.inc drupal_set_message($message = NULL, $type = 'status', $repeat = FALSE)
4.6.x bootstrap.inc drupal_set_message($message = NULL, $type = 'status')
4.7.x bootstrap.inc drupal_set_message($message = NULL, $type = 'status')
5.x bootstrap.inc drupal_set_message($message = NULL, $type = 'status')
6.x bootstrap.inc drupal_set_message($message = NULL, $type = 'status', $repeat = TRUE)
7.x bootstrap.inc drupal_set_message($message = NULL, $type = 'status', $repeat = TRUE)

Sets a message to display to the user.

Messages are stored in a session variable and displayed in page.tpl.php via the $messages theme variable.

Example usage:

drupal_set_message(t('An error occurred and processing did not complete.'), 'error');


string $message: (optional) The translated message to be displayed to the user. For consistency with other messages, it should begin with a capital letter and end with a period.

string $type: (optional) The message's type. Defaults to 'status'. These values are supported:

  • 'status'
  • 'warning'
  • 'error'

bool $repeat: (optional) If this is FALSE and the message is already set, then the message won't be repeated. Defaults to TRUE.

Return value

array|null A multidimensional array with keys corresponding to the set message types. The indexed array values of each contain the set messages for that type. Or, if there are no messages set, the function returns NULL.

See also



241 calls to drupal_set_message()
aggregator_aggregator_remove in modules/aggregator/aggregator.processor.inc
Implements hook_aggregator_remove().
aggregator_categorize_items_submit in modules/aggregator/aggregator.pages.inc
Form submission handler for aggregator_categorize_items().
aggregator_form_category_submit in modules/aggregator/aggregator.admin.inc
Form submission handler for aggregator_form_category().
aggregator_form_feed_submit in modules/aggregator/aggregator.admin.inc
Form submission handler for aggregator_form_feed().
aggregator_form_opml_submit in modules/aggregator/aggregator.admin.inc
Form submission handler for aggregator_form_opml().

... See full list


includes/bootstrap.inc, line 2054
Functions that need to be loaded on every Drupal request.


function drupal_set_message($message = NULL, $type = 'status', $repeat = TRUE) {
  if ($message || $message === '0' || $message === 0) {
    if (!isset($_SESSION['messages'][$type])) {
      $_SESSION['messages'][$type] = array();
    if ($repeat || !in_array($message, $_SESSION['messages'][$type])) {
      $_SESSION['messages'][$type][] = $message;

    // Mark this page as being uncacheable.

  // Messages not set when DB connection fails.
  return isset($_SESSION['messages']) ? $_SESSION['messages'] : NULL;


BarisW’s picture

You can use


to clear all status messages and leave errors intact.

DamienMcKenna’s picture

This function does not automatically translate messages so it is important to translate them first, e.g.:

  drupal_set_message(t("Don't panic!"), 'warning');
seismicmike’s picture

It'd be nice if drupal_set_message had t() built in a la watchdog.

drupal_set_message($message = NULL, $args = NULL, $type = 'status', $repeat = TRUE)

drupal_set_message('Hello :name', array(':name' => $name));

Just a thought.

kingandy’s picture

I'd agree, maybe this should be raised as a feature request. As drupal_set_message is fairly widely-used it's unlikely to be changed in a minor release, but maybe a future major version could incorporate this?

As both 'type' and 'args' would be optional, maybe it be worth moving over to a single url() style 'options' argument:

 drupal_set_message($message = NULL, $options = array()) {
  // Merge in defaults.
  $options += array(
    'args' => array(), 
    'type' => 'status', 
    'repeat' => TRUE,
  // ...
a6hiji7’s picture

I agree too. Also drupal_set_message() uses hardcoded strings like 'warning' for the type, where constants would have been much better. In fact drupal_set_message() and watchdog() could be merged into a single function, with an option to set the message either in the UI, like drupal_set_message() or allowing the logging to be handled by another module like watchdog.

aaronaverill’s picture

Note that the $type parameter can be anything you like and is passed directly through to the rendered div's class attribute. For example the following:

drupal_set_message(t('Something horrible just happened.'),'nuke');

generates this HTML:
<div class="messages nuke"> Something horrible just happened.</div>

Which can be styled with the following CSS:

div.nuke, table tr.nuke {
    background-color: #FF5EBE;
div.nuke, .nuke {
    color: #6B3A61;
div.nuke {
    background-image: url("nuke.png");
    border-color: #FFFA00;

Be sure the background image "nuke.png" above is 24x24 pixels which will ensure the borders and padding work out nicely.

CarlHinton’s picture

Do meet Drupal standards and to ensure that everything is done securely this should be implemented as:

drupal_set_message(check_plain(t('Something !var just happened.'), array('!var' => $horrible)),'nuke');
Kiphaas7’s picture

@CarlHinton and coding standards:

drupal_set_message(t('Something @var just happened.'), array('@var' => $horrible), 'nuke'); 

Would probably be a better choice, since @ does a check_plain for you. Also see: format_string

qasimzee’s picture

Your code returns a compile time error:

Warning: Illegal offset type in drupal_set_message() (line 1785 of /site/includes/bootstrap.inc).

marblegravy’s picture

The brackets were just in the wrong place. Try this one:

drupal_set_message(t('Something @var just happened.', array('@var' => $pleasant)), 'butterflies'); 
danithaca’s picture

To alter messages, e.g., hide the "Further instructions have been sent to you by email", see http://stackoverflow.com/questions/4942785/alter-messages-in-drupal-7, or https://drupal.org/node/162697.

This is how it works:

function mymodule_preprocess_status_messages(&$variables) {
  $message = 'Further instructions have been sent to your e-mail address.';
  if (isset($_SESSION['messages'])) {
    foreach ($_SESSION['messages'] as $type => $messages) {
      if ($type == 'status') {
        $pos = array_search($message, $messages);
        if ($pos !== FALSE) {
texas-bronius’s picture

Thanks for the simple example! I just wanted to add that hook_preprocess_status_messages happens after watchdog has already heard of it. You might be getting clever and silencing or changing some PHP Notices, for instance, but they'll still clutter watchdog.

kostya_ck’s picture

How does work argument $repeat? What is its meaning?

minorOffense’s picture

If you're looping over something and it's generating identical messages if repeat is true it will print that same message over and over again. If repeat is false then it will only print the first occurrence of that message.

aks22’s picture

danithaca your code worked for me.

ssibal’s picture

I was wondering if there is a working service for this in D8, not to use procedural code. I found 'session.flash_bag' but it's not public, and you can't inject it.
Any ideas on this?