Ah ha. Found it. Looks like the dev guys accounted for this.
You can see how in org.apache.struts.validator.Resources. public static ActionMessage getActionMessage(Validator validator, HttpServletRequest request, ValidatorAction va, Field field) { Msg msg = field.getMessage(va.getName()); if ((msg != null) && !msg.isResource()) { return new ActionMessage(msg.getKey(), false); } So if you've configured your validation.xml field entry to indicate that the message isn't a resource, Struts creates an ActionMessage which interprets it as a literal value, not as a key into a resource bundle. Certainly is nice to have the i18n option when you need it, but when you know you don't, it's quite a bit of clutter to support. Thanks! Stu