diff --git a/doc/api/deprecations.md b/doc/api/deprecations.md
index a5386f7bf015af..1f5809624afe95 100644
--- a/doc/api/deprecations.md
+++ b/doc/api/deprecations.md
@@ -871,6 +871,15 @@ Type: Runtime
`timers.unenroll()` is deprecated. Please use the publicly documented [`clearTimeout()`][] or [`clearInterval()`][] instead.
+
+### DEP0097: MakeCallback with domain property
+
+Type: Runtime
+
+Users of `MakeCallback` that add the `domain` property to carry context,
+should start using the `async_context` variant of `MakeCallback` or
+`CallbackScope`, or the the high-level `AsyncResource` class.
+
[`--pending-deprecation`]: cli.html#cli_pending_deprecation
[`Buffer.allocUnsafeSlow(size)`]: buffer.html#buffer_class_method_buffer_allocunsafeslow_size
[`Buffer.from(array)`]: buffer.html#buffer_class_method_buffer_from_array
diff --git a/lib/domain.js b/lib/domain.js
index 08fbd207f171d3..be109c9ce056bd 100644
--- a/lib/domain.js
+++ b/lib/domain.js
@@ -94,13 +94,29 @@ process.setUncaughtExceptionCaptureCallback = function(fn) {
throw err;
};
+
+let sendMakeCallbackDeprecation = false;
+function emitMakeCallbackDeprecation() {
+ if (!sendMakeCallbackDeprecation) {
+ process.emitWarning(
+ 'Using a domain property in MakeCallback is deprecated. Use the ' +
+ 'async_context variant of MakeCallback or the AsyncResource class ' +
+ 'instead.', 'DeprecationWarning', 'DEP0097');
+ sendMakeCallbackDeprecation = true;
+ }
+}
+
function topLevelDomainCallback(cb, ...args) {
const domain = this.domain;
+ if (exports.active && domain)
+ emitMakeCallbackDeprecation();
+
if (domain)
domain.enter();
const ret = Reflect.apply(cb, this, args);
if (domain)
domain.exit();
+
return ret;
}
diff --git a/test/addons/make-callback-domain-warning/binding.cc b/test/addons/make-callback-domain-warning/binding.cc
new file mode 100644
index 00000000000000..c42166c7455277
--- /dev/null
+++ b/test/addons/make-callback-domain-warning/binding.cc
@@ -0,0 +1,31 @@
+#include "node.h"
+#include "v8.h"
+
+#include
+
+using v8::Function;
+using v8::FunctionCallbackInfo;
+using v8::Isolate;
+using v8::Local;
+using v8::Object;
+using v8::Value;
+
+namespace {
+
+void MakeCallback(const FunctionCallbackInfo& args) {
+ assert(args[0]->IsObject());
+ assert(args[1]->IsFunction());
+ Isolate* isolate = args.GetIsolate();
+ Local