Is it possible to give inactive accounts a custom error message upon login?
You can alter the login form and add a custom validator where you check if user is blocked and show the error message you want.

If you check the code you'll see that login validator are set by the user_login_default_validators() function. Those validators are:


user_login_name_validate
user_login_authenticate_validate
user_login_final_validate


What I don't understand is why are you getting the "wrong username/password" (actually the message is "Sorry, unrecognized username or password. Have you forgotten your password?"). The first validator checks if the user is blocked:

/**
 * A FAPI validate handler. Sets an error if supplied username has been blocked.
 */
function user_login_name_validate($form, &amp;$form_state) {
  if (!empty($form_state['values']['name']) &amp;&amp; user_is_blocked($form_state['values']['name'])) {
    // Blocked in user administration.
    form_set_error('name', t('The username %name has not been activated or is blocked.', array('%name' =&gt; $form_state['values']['name'])));
  }
}


As you can see when a user is blocked the message es "The username %name has not been activated or is blocked".

Anyway, to achieve what you want I think you ca follow the steps:

Implement hook_form_FORM_ID_alter adding your custom validator as
FIRST validator. You have to alter two forms, 'user_login' and
'user_form_block' (tose are the form ids). Use:

array_unshift($form['#validate'], 'my_custom_user_validation');


to add your custom validator as first validator.

Then code your custom validator. It should be same as user_login_name_validate but using your custom message.

Edit: As I've pointed out in my answer and J. Reynolds says the blocked message is not the standard wrong user/password. If you get the blocked user message you can go with J. Reynolds suggestion (just altering the standard user blocked message). If you need to check for any other different condition (for example, blocked and spam role) you can use what I say in this answer.