diff --git a/lustre/ChangeLog b/lustre/ChangeLog
index 40afede364f08627140b8b5a5367af57351bb92a..7ab7e35251ab74130aeecbaa0b228393577dddf1 100644
--- a/lustre/ChangeLog
+++ b/lustre/ChangeLog
@@ -14,6 +14,13 @@ tbd         Cluster File Systems, Inc. <info@clusterfs.com>
        * Note that reiserfs quotas are disabled on SLES 10 in this kernel.
        * bug fixes
 
+Severity   : normal
+Frequency  : rare
+Bugzilla   : 12470
+Description: server LBUG when using old ost_num_threads parameter
+Details    : Accept the old ost_num_threads parameter but warn that it
+	     is deprecated, and fix an off-by-one error that caused an LBUG.
+
 Severity   : normal
 Frequency  : rare
 Bugzilla   : 11722
diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c
index 78672c9d29e1b6651b2944668f91388e3bf1dc5b..162caa23a40167e084fb12fadfd2cd650a9f534a 100644
--- a/lustre/ost/ost_handler.c
+++ b/lustre/ost/ost_handler.c
@@ -55,6 +55,10 @@ static int oss_num_threads;
 CFS_MODULE_PARM(oss_num_threads, "i", int, 0444,
                 "number of OSS service threads to start");
 
+static int ost_num_threads;
+CFS_MODULE_PARM(ost_num_threads, "i", int, 0444,
+                "number of OST service threads to start (deprecated)");
+
 void oti_to_request(struct obd_trans_info *oti, struct ptlrpc_request *req)
 {
         struct oti_req_ack_lock *ack_lock;
@@ -1604,7 +1608,7 @@ static int ost_thread_init(struct ptlrpc_thread *thread)
 
         LASSERT(thread != NULL);
         LASSERT(thread->t_data == NULL);
-        LASSERT(thread->t_id <= OSS_THREADS_MAX);
+        LASSERTF(thread->t_id <= OSS_THREADS_MAX, "%u\n", thread->t_id);
 
         OBD_ALLOC_PTR(tls);
         if (tls != NULL) {
@@ -1809,6 +1813,14 @@ static int __init ost_init(void)
         lprocfs_init_vars(ost, &lvars);
         rc = class_register_type(&ost_obd_ops, lvars.module_vars,
                                  LUSTRE_OSS_NAME);
+
+        if (ost_num_threads != 0 && oss_num_threads == 0) {
+                LCONSOLE_INFO("ost_num_threads module parameter is deprecated, "
+                              "use oss_num_threads instead or unset both for "
+                              "dynamic thread startup\n");
+                oss_num_threads = ost_num_threads;
+        }
+
         RETURN(rc);
 }
 
diff --git a/lustre/ptlrpc/service.c b/lustre/ptlrpc/service.c
index c1bca2145cc1ae2effdc53b63ccc29df68327a57..7b5aa0ccc8a8e06e8c261a378ea60af4541332a6 100644
--- a/lustre/ptlrpc/service.c
+++ b/lustre/ptlrpc/service.c
@@ -1090,7 +1090,7 @@ int ptlrpc_start_thread(struct obd_device *dev, struct ptlrpc_service *svc)
         CDEBUG(D_RPCTRACE, "%s started %d min %d max %d running %d\n",
                svc->srv_name, svc->srv_threads_started, svc->srv_threads_min,
                svc->srv_threads_max, svc->srv_threads_running);
-        if (svc->srv_threads_started >= svc->srv_threads_max) 
+        if (svc->srv_threads_started >= svc->srv_threads_max)
                 RETURN(-EMFILE);
 
         OBD_ALLOC(thread, sizeof(*thread));
@@ -1105,7 +1105,7 @@ int ptlrpc_start_thread(struct obd_device *dev, struct ptlrpc_service *svc)
                 RETURN(-EMFILE);
         }
         list_add(&thread->t_link, &svc->srv_threads);
-        id = ++svc->srv_threads_started;
+        id = svc->srv_threads_started++;
         spin_unlock(&svc->srv_lock);
 
         thread->t_id = id;