diff --git a/changes/bug6244_part_c b/changes/bug6244_part_c
new file mode 100644
index 0000000000000000000000000000000000000000..dea6e7b69edc5c697898d94f88e3e056cf24abc1
--- /dev/null
+++ b/changes/bug6244_part_c
@@ -0,0 +1,6 @@
+  o Major bugfixes (controller):
+    - Make wildcarded addresses (that is, ones beginning with *.) work when
+      provided via the controller's MapAddress command.  Previously, they
+      were accepted, but we never actually noticed that they were wildcards.
+      Fix for bug 6244; bugfix on 0.2.3.9-alpha.
+
diff --git a/src/or/config.c b/src/or/config.c
index 639abcdb4778298e634bd81e0956d1a81e70d009..3970808fb30a53b8d37893c9ebcfdede9d787f6a 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -4871,12 +4871,11 @@ config_register_addressmaps(const or_options_t *options)
 {
   smartlist_t *elts;
   config_line_t *opt;
-  char *from, *to;
+  const char *from, *to, *msg;
 
   addressmap_clear_configured();
   elts = smartlist_new();
   for (opt = options->AddressMap; opt; opt = opt->next) {
-    int from_wildcard = 0, to_wildcard = 0;
     smartlist_split_string(elts, opt->value, NULL,
                            SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 2);
     if (smartlist_len(elts) < 2) {
@@ -4894,11 +4893,39 @@ config_register_addressmaps(const or_options_t *options)
       goto cleanup;
     }
 
-    if (!strcmp(to, "*") || !strcmp(from, "*")) {
-      log_warn(LD_CONFIG,"MapAddress '%s' is unsupported - can't remap from "
-               "or to *. Ignoring.",opt->value);
+    if (addressmap_register_auto(from, to, 0, ADDRMAPSRC_TORRC, &msg) < 0) {
+      log_warn(LD_CONFIG,"MapAddress '%s' failed: %s. Ignoring.", opt->value,
+               msg);
       goto cleanup;
     }
+
+    if (smartlist_len(elts) > 2)
+      log_warn(LD_CONFIG,"Ignoring extra arguments to MapAddress.");
+
+  cleanup:
+    SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
+    smartlist_clear(elts);
+  }
+  smartlist_free(elts);
+}
+
+/** As addressmap_register(), but detect the wildcarded status of "from" and
+ * "to", and do not steal a reference to <b>to</b>. */
+/* XXXX024 move to connection_edge.c */
+int
+addressmap_register_auto(const char *from, const char *to,
+                         time_t expires,
+                         addressmap_entry_source_t addrmap_source,
+                         const char **msg)
+{
+  int from_wildcard = 0, to_wildcard = 0;
+
+  *msg = "whoops, forgot the error message";
+  if (1) {
+    if (!strcmp(to, "*") || !strcmp(from, "*")) {
+      *msg = "can't remap from or to *";
+      return -1;
+    }
     /* Detect asterisks in expressions of type: '*.example.com' */
     if (!strncmp(from,"*.",2)) {
       from += 2;
@@ -4910,30 +4937,20 @@ config_register_addressmaps(const or_options_t *options)
     }
 
     if (to_wildcard && !from_wildcard) {
-      log_warn(LD_CONFIG,
-                "Skipping invalid argument '%s' to MapAddress: "
-                "can only use wildcard (i.e. '*.') if 'from' address "
-                "uses wildcard also", opt->value);
-      goto cleanup;
+      *msg =  "can only use wildcard (i.e. '*.') if 'from' address "
+        "uses wildcard also";
+      return -1;
     }
 
     if (address_is_invalid_destination(to, 1)) {
-      log_warn(LD_CONFIG,
-                "Skipping invalid argument '%s' to MapAddress", opt->value);
-      goto cleanup;
+      *msg = "destination is invalid";
+      return -1;
     }
 
-    addressmap_register(from, tor_strdup(to), 0, ADDRMAPSRC_TORRC,
+    addressmap_register(from, tor_strdup(to), expires, addrmap_source,
                         from_wildcard, to_wildcard);
-
-    if (smartlist_len(elts) > 2)
-      log_warn(LD_CONFIG,"Ignoring extra arguments to MapAddress.");
-
-  cleanup:
-    SMARTLIST_FOREACH(elts, char*, cp, tor_free(cp));
-    smartlist_clear(elts);
   }
-  smartlist_free(elts);
+  return 0;
 }
 
 /**
diff --git a/src/or/config.h b/src/or/config.h
index ce7e319746199c456ac2609e8305a1eb4c9c99d3..48f4e8630c024bbc53e5287229f825213205bf90 100644
--- a/src/or/config.h
+++ b/src/or/config.h
@@ -96,6 +96,12 @@ or_options_t *options_new(void);
 #endif
 
 void config_register_addressmaps(const or_options_t *options);
+/* XXXX024 move to connection_edge.h */
+int addressmap_register_auto(const char *from, const char *to,
+                             time_t expires,
+                             addressmap_entry_source_t addrmap_source,
+                             const char **msg);
+
 
 #endif
 
diff --git a/src/or/control.c b/src/or/control.c
index ce571f99f385f3b4b62e5bb37b5d52d90cea1626..913d18a7fc18f58cfcd4251be18c474952697e4d 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -1366,9 +1366,18 @@ handle_control_mapaddress(control_connection_t *conn, uint32_t len,
           smartlist_add_asprintf(reply, "250-%s=%s", address, to);
         }
       } else {
-        addressmap_register(from, tor_strdup(to), 1,
-                            ADDRMAPSRC_CONTROLLER, 0, 0);
-        smartlist_add_asprintf(reply, "250-%s", line);
+        const char *msg;
+        if (addressmap_register_auto(from, to, 1,
+                                     ADDRMAPSRC_CONTROLLER, &msg) < 0) {
+          smartlist_add_asprintf(reply,
+                                 "512-syntax error: invalid address mapping "
+                                 " '%s': %s", line, msg);
+          log_warn(LD_CONTROL,
+                   "Skipping invalid argument '%s' in MapAddress msg: %s",
+                   line, msg);
+        } else {
+          smartlist_add_asprintf(reply, "250-%s", line);
+        }
       }
     } else {
       smartlist_add_asprintf(reply, "512-syntax error: mapping '%s' is "